Revision history for Perl distribution Excel::Template
+0.24 ??? Mar 0? ??:00:00 2005
+ - Improved code coverage with more and better tests
+
0.23 Fri Feb 25 15:00:00 2005
- Improved code coverage with more and better tests
- Fixed POD bug with Devel::Cover results
t/017_filehandle.t
t/018_register.t
t/019_output.t
-t/pod.t
-t/pod_coverage.t
+t/020_worksheet_attributes.t
+t/998_pod.t
+t/999_pod_coverage.t
t/mock.pm
t/Register_018.pm
t/Spreadsheet/WriteExcel.pm
# Devel::Cover
^cover_db/?
+^tags?
+.err?
+
+# developer-only tests
+^dev_.*\.t$
}
my $prereqs = {
- 'Spreadsheet::WriteExcel' => 0.42,
'Test::More' => 0.01,
'XML::Parser' => 0.01,
'IO::Scalar' => 0.01,
'File::Basename' => 0.01,
+ 'Spreadsheet::WriteExcel' => 0.42,
+ 'Spreadsheet::WriteExcel::Utility' => 0.01,
};
# The assumption is Perl 5.8.0 and greater doesn't need Unicode::String.
use Excel::Template::Base;
use vars qw ($VERSION @ISA);
- $VERSION = '0.23';
+ $VERSION = '0.24';
@ISA = qw( Excel::Template::Base );
}
my $self = shift;
# Allow an arbitrary number of hashrefs, so long as they're the first things # into param(). Put each one onto the end, de-referenced.
- push @_, %{shift @_} while UNIVERSAL::isa($_[0], 'HASH');
+ push @_, %{shift @_} while ref $_[0] eq 'HASH';
(@_ % 2)
&& die __PACKAGE__, "->param() : Odd number of parameters to param()\n";
my $xls = $self->{RENDERER}->new($filename)
|| die "Cannot create XLS in '$filename': $!\n";
- $self->_prepare_output($xls);
+ eval {
+ $self->_prepare_output($xls);
+ };
$xls->close;
+ return if $@;
+
return ~~1;
}
my $output;
tie *XLS, 'IO::Scalar', \$output;
- $self->write_file(\*XLS);
+ $self->write_file(\*XLS)
+ or return;
return $output;
}
if ( $node->isa( 'WORKBOOK' ) )
{
- push @{$self->{WORKBOOKS}}, $node;
+ $self->{WORKBOOK} = $node;
}
elsif ( $node->is_embedded )
{
my $parser = XML::Parser->new( @parms );
$parser->parse(do { local $/ = undef; <INFILE> });
- unless ( ref $file )
- {
- close INFILE;
- }
+ close INFILE
+ unless ref $file;
return ~~1;
}
-*parse = \&parse_xml;
+*parse = *parse = \&parse_xml;
sub _prepare_output
{
my $self = shift;
+ return unless $self->{WORKBOOK};
+
my ($xls) = @_;
my $context = Excel::Template::Factory->_create(
UNICODE => $self->{UNICODE},
);
- $_->render($context) for @{$self->{WORKBOOKS}};
+ $self->{WORKBOOK}->render($context);
return ~~1;
}
use strict;
-BEGIN {
-}
-
use Excel::Template::Factory;
sub new
{
my $class = shift;
-
- push @_, %{shift @_} while defined $_[0] && UNIVERSAL::isa($_[0], 'HASH');
- (@_ % 2)
+
+ push @_, %{shift @_} while ref $_[0] eq 'HASH';
+ (@_ % 2)
and die "$class->new() called with odd number of option parameters\n";
-
+
my %x = @_;
-
+
# Do not use a hashref-slice here because of the uppercase'ing
my $self = {};
$self->{uc $_} = $x{$_} for keys %x;
-
+
bless $self, $class;
}
-
-sub isa { Excel::Template::Factory::isa(@_) }
-sub is_embedded { Excel::Template::Factory::is_embedded(@_) }
+
+*isa = *isa = \&Excel::Template::Factory::isa;
+*is_embedded = *is_embedded = \&Excel::Template::Factory::is_embedded;
#sub calculate { ($_[1])->get(@_[0,2]) }
#{
#
# return $context->get($self, $attr);
#}
-
+
sub enter_scope { ($_[1])->enter_scope($_[0]) }
#{
# my $self = shift;
#
# return $context->enter_scope($self);
#}
-
-sub exit_scope { ($_[1])->exit_scope(@_[0, 2]) }
+
+sub exit_scope { ($_[1])->exit_scope($_[0], $_[2]) }
#{
# my $self = shift;
# my ($context, $no_delta) = @_;
#
# return $context->exit_scope($self, $no_delta);
#}
-
+
sub deltas
{
# my $self = shift;
# my ($context) = @_;
-
+
return {};
}
-
-sub resolve
-{
+
+# Everyone seems to have their own versions.
+# Maybe, it's part of the API to require that you have the right one of these
+# defined?
+#sub resolve
+#{
# my $self = shift;
# my ($context) = @_;
-
- '';
-}
-
-sub render
-{
+#
+# '';
+#}
+#
+#sub render
+#{
# my $self = shift;
# my ($context) = @_;
-
- 1;
-}
+#
+# 1;
+#}
1;
__END__
$self->{ELEMENTS} = []
unless exists $self->{ELEMENTS} &&
- UNIVERSAL::isa($self->{ELEMENTS}, 'ARRAY');
+ ref $self->{ELEMENTS} eq 'ARRAY';
return $self;
}
-sub _do_page
-{
- my $self = shift;
- my ($method, $context) = @_;
-
- for my $e (@{$self->{ELEMENTS}})
- {
- $e->enter_scope($context);
- $e->$method($context);
- $e->exit_scope($context, 1);
- }
-
- return 1;
-}
-
-sub begin_page { _do_page 'begin_page', @_ }
-sub end_page { _do_page 'end_page', @_ }
+# Removed as unused code
+#sub _do_page
+#{
+# my $self = shift;
+# my ($method, $context) = @_;
+#
+# for my $e (@{$self->{ELEMENTS}})
+# {
+# $e->enter_scope($context);
+# $e->$method($context);
+# $e->exit_scope($context, 1);
+# }
+#
+# return 1;
+#}
+#
+#sub begin_page { _do_page 'begin_page', @_ }
+#sub end_page { _do_page 'end_page', @_ }
sub iterate_over_children
{
# return $self->iterate_over_children($context);
#}
+# Removed as unused code
#sub max_of
#{
# my $self = shift;
return 0 unless $name =~ /\S/;
my $val = $context->param($name);
- $val = @{$val} while UNIVERSAL::isa($val, 'ARRAY');
- $val = ${$val} while UNIVERSAL::isa($val, 'SCALAR');
+ $val = @{$val} while ref $val eq 'ARRAY';
+ $val = ${$val} while ref $val eq 'SCALAR';
my $value = $context->get($self, 'VALUE');
if (defined $value)
$context->active_worksheet->protect( $password );
}
+ my $keep_zeros = $context->get( $self, 'KEEP_LEADING_ZEROS' );
+ if ( defined $keep_zeros )
+ {
+ $context->active_worksheet->keep_leading_zeros( $keep_zeros ? 1 : 0 );
+ }
+
return $self->SUPER::render($context);
}
This activates the HIDDEN and LOCKED nodes.
+=item * KEEP_LEADING_ZEROS
+
+This will change the behavior of the worksheet to preserve leading zeros.
+
=back
=head1 CHILDREN
# Removed NAME_MAP until I figure out what the heck it's for
for (qw( STACK PARAM_MAP ))
{
- next if defined $self->{$_} && UNIVERSAL::isa($self->{$_}, 'ARRAY');
+ next if defined $self->{$_} && ref $self->{$_} eq 'ARRAY';
$self->{$_} = [];
}
use strict;
-BEGIN {
- use vars qw(%Manifest %isBuildable);
-}
-
-%Manifest = (
+my %Manifest = (
# These are the instantiable nodes
'IF' => 'Excel::Template::Container::Conditional',
'BASE' => 'Excel::Template::Base',
);
-%isBuildable = map { $_ => ~~1 } qw(
- BOLD
- CELL
- FORMAT
- FORMULA
- IF
- HIDDEN
- ITALIC
- LOCKED
- OUTLINE
- LOOP
- BACKREF
- RANGE
- ROW
- SCOPE
- SHADOW
- STRIKEOUT
- VAR
- WORKBOOK
- WORKSHEET
+my %isBuildable = map { $_ => ~~1 } qw(
+ WORKBOOK WORKSHEET
+ FORMAT BOLD HIDDEN ITALIC LOCKED OUTLINE SHADOW STRIKEOUT
+ IF ROW LOOP SCOPE
+ CELL FORMULA
+ VAR BACKREF RANGE
);
-sub _load_class
{
- my $self = shift;
- my ($class) = @_;
+ my %Loaded;
+ sub _load_class
+ {
+ my $self = shift;
+ my ($class) = @_;
- (my $filename = $class) =~ s!::!/!g;
- eval {
- require "$filename.pm";
- }; if ($@) {
- die "Cannot find or compile PM file for '$class' ($filename)\n";
- }
+ unless ( exists $Loaded{$class} )
+ {
+ (my $filename = $class) =~ s!::!/!g;
+ eval {
+ require "$filename.pm";
+ }; if ($@) {
+ die "Cannot find or compile PM file for '$class' ($filename)\n";
+ }
+
+ $Loaded{$class} = ~~1;
+ }
- return ~~1;
+ return ~~1;
+ }
}
{
# Cache the reference to the appropriate data.
$self->{DATA} = $self->{CONTEXT}->param($self->{NAME});
- unless (UNIVERSAL::isa($self->{DATA}, 'ARRAY'))
+ unless (ref $self->{DATA} eq 'ARRAY')
{
$self->{NO_PARAMS} = 1;
warn "'$self->{NAME}' does not have a list of parameters", $/ if $^W;
$self->{STACK} = []
unless defined $self->{STACK} &&
- UNIVERSAL::isa($self->{STACK}, 'ARRAY');
+ ref $self->{STACK} eq 'ARRAY';
return $self;
}
--- /dev/null
+use strict;
+
+use Test::More tests => 4;
+
+use lib 't';
+use mock;
+mock::reset;
+
+my $CLASS = 'Excel::Template';
+use_ok( $CLASS );
+
+my $object = $CLASS->new(
+ filename => \*DATA,
+);
+isa_ok( $object, $CLASS );
+
+ok( $object->write_file( 'filename' ), 'Something returned' );
+
+my @calls = mock::get_calls;
+is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' );
+Spreadsheet::WriteExcel::new( 'filename' )
+Spreadsheet::WriteExcel::add_format( '' )
+Spreadsheet::WriteExcel::add_worksheet( 'worksheet attributes' )
+Spreadsheet::WriteExcel::Worksheet::new( '' )
+Spreadsheet::WriteExcel::Worksheet::keep_leading_zeros( '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '0', '03', '1' )
+Spreadsheet::WriteExcel::close( '' )
+__END_EXPECTED__
+
+__DATA__
+<workbook>
+ <worksheet name="worksheet attributes" keep_leading_zeros="1">
+ <cell text="03" />
+ </worksheet>
+</workbook>
--- /dev/null
+BEGIN{ $^W = 0 }
+use strict;
+
+use Test::More tests => 4;
+
+use lib 't';
+use mock;
+mock::reset;
+
+my $CLASS = 'Excel::Template';
+use_ok( $CLASS );
+
+my $object = $CLASS->new(
+ file => \*DATA,
+);
+isa_ok( $object, $CLASS );
+
+ok(
+ $object->param(
+ test => [
+ { value => 1 },
+ { value => 2 },
+ [ value => 3 ],
+ ],
+ ),
+ 'Parameters set',
+);
+
+ok( !$object->write_file( 'filename' ), 'Failed to write file' );
+
+__DATA__
+<workbook>
+ <worksheet>
+ <loop name="test">
+ <cell text="$value" />
+ </loop>
+ </worksheet>
+</workbook>
}
}
+sub keep_leading_zeros {
+ my $self = shift;
+
+ {
+ local $" = "', '";
+ push @mock::calls, __PACKAGE__ . "::keep_leading_zeros( '@_' )";
+ }
+}
+
1;
__END__
--- /dev/null
+use strict;
+
+use Test::More;
+
+use lib 't';
+
+eval "use Test::Distribution not => 'versions'";
+plan skip_all => "Test::Distribution required for testing DISTRIBUTION coverage" if $@;
-#!/usr/bin/perl
-
use strict;
use Test::More;
-#!/usr/bin/perl
-
use strict;
use Test::More;
# These are methods that need naming work
my @private_methods = qw(
render new min max resolve deltas
- begin_page end_page
enter_scope exit_scope iterate_over_children
);
# These are method names that have been commented out, for now
# max_of total_of
+# begin_page end_page
my $private_regex = do {
local $"='|';
--- /dev/null
+!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
+!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
+!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
+!_TAG_PROGRAM_NAME Exuberant Ctags //
+!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
+!_TAG_PROGRAM_VERSION 5.5.4 //
+PROPERTY lib/Excel/Template/Format.pm /^ PROPERTY:$/;" l
+RENDER_BIG lib/Excel/Template.pm /^use constant RENDER_BIG => 'big';$/;" c
+RENDER_NML lib/Excel/Template.pm /^use constant RENDER_NML => 'normal';$/;" c
+RENDER_XML lib/Excel/Template.pm /^use constant RENDER_XML => 'xml';$/;" c
+UNIVERSAL lib/Excel/Template/Container.pm /^ UNIVERSAL::isa($self->{ELEMENTS}, 'ARRAY');$/;" l
+UNIVERSAL lib/Excel/Template/TextObject.pm /^ UNIVERSAL::isa($self->{STACK}, 'ARRAY');$/;" l
+_assign lib/Excel/Template/Format.pm /^ sub _assign { $_Formats{$_[0]} = $_[1]; $_Formats{$_[1]} = $_[0] }$/;" s
+_conditional_passes lib/Excel/Template/Container/Conditional.pm /^sub _conditional_passes$/;" s
+_create lib/Excel/Template/Factory.pm /^sub _create$/;" s
+_create_node lib/Excel/Template/Factory.pm /^sub _create_node$/;" s
+_do_globals lib/Excel/Template/Iterator.pm /^sub _do_globals$/;" s
+_do_page lib/Excel/Template/Container.pm /^sub _do_page$/;" s
+_find_param_in_map lib/Excel/Template/Context.pm /^sub _find_param_in_map$/;" s
+_get_text lib/Excel/Template/Element/Cell.pm /^sub _get_text$/;" s
+_key_to_params lib/Excel/Template/Format.pm /^ sub _key_to_params$/;" s
+_load_class lib/Excel/Template/Factory.pm /^sub _load_class$/;" s
+_make_iterator lib/Excel/Template/Container/Loop.pm /^sub _make_iterator$/;" s
+_params_to_key lib/Excel/Template/Format.pm /^ sub _params_to_key$/;" s
+_prepare_output lib/Excel/Template.pm /^sub _prepare_output$/;" s
+_retrieve_key lib/Excel/Template/Format.pm /^ sub _retrieve_key { $_Formats{ $_[0] } }$/;" s
+active_format lib/Excel/Template/Context.pm /^sub active_format$/;" s
+active_worksheet lib/Excel/Template/Context.pm /^sub active_worksheet$/;" s
+add_format t/Spreadsheet/WriteExcel.pm /^sub add_format {$/;" s
+add_reference lib/Excel/Template/Context.pm /^sub add_reference$/;" s
+add_worksheet t/Spreadsheet/WriteExcel.pm /^sub add_worksheet {$/;" s
+begin_page lib/Excel/Template/Container.pm /^sub begin_page { _do_page 'begin_page', @_ }$/;" s
+blank_format lib/Excel/Template/Format.pm /^sub blank_format$/;" s
+can_continue lib/Excel/Template/Iterator.pm /^sub can_continue$/;" s
+close t/Spreadsheet/WriteExcel.pm /^sub close {$/;" s
+copy lib/Excel/Template/Format.pm /^ sub copy$/;" s
+deltas lib/Excel/Template/Base.pm /^sub deltas$/;" s
+deltas lib/Excel/Template/Container/Row.pm /^sub deltas$/;" s
+deltas lib/Excel/Template/Element/Cell.pm /^sub deltas$/;" s
+end_page lib/Excel/Template/Container.pm /^sub end_page { _do_page 'end_page', @_ }$/;" s
+enter_scope lib/Excel/Template/Base.pm /^sub enter_scope { ($_[1])->enter_scope($_[0]) }$/;" s
+enter_scope lib/Excel/Template/Context.pm /^sub enter_scope$/;" s
+enter_scope lib/Excel/Template/Iterator.pm /^sub enter_scope$/;" s
+exit_scope lib/Excel/Template/Base.pm /^sub exit_scope { ($_[1])->exit_scope(@_[0, 2]) }$/;" s
+exit_scope lib/Excel/Template/Context.pm /^sub exit_scope$/;" s
+exit_scope lib/Excel/Template/Iterator.pm /^sub exit_scope$/;" s
+get lib/Excel/Template/Context.pm /^sub get$/;" s
+get_all_references lib/Excel/Template/Context.pm /^sub get_all_references$/;" s
+get_calls t/mock.pm /^sub get_calls { @calls }$/;" s
+get_last_reference lib/Excel/Template/Context.pm /^sub get_last_reference$/;" s
+is_embedded lib/Excel/Template/Base.pm /^sub is_embedded { Excel::Template::Factory::is_embedded(@_) }$/;" s
+is_embedded lib/Excel/Template/Factory.pm /^sub is_embedded$/;" s
+isa lib/Excel/Template/Base.pm /^sub isa { Excel::Template::Factory::isa(@_) }$/;" s
+isa lib/Excel/Template/Factory.pm /^sub isa$/;" s
+iterate_over_children lib/Excel/Template/Container.pm /^sub iterate_over_children$/;" s
+max lib/Excel/Template/Element/Range.pm /^sub max { $_[0] > $_[1] ? $_[0] : $_[1] }$/;" s
+min lib/Excel/Template/Element/Range.pm /^sub min { $_[0] < $_[1] ? $_[0] : $_[1] }$/;" s
+more_params lib/Excel/Template/Iterator.pm /^sub more_params$/;" s
+new lib/Excel/Template.pm /^sub new$/;" s
+new lib/Excel/Template/Base.pm /^sub new$/;" s
+new lib/Excel/Template/Container.pm /^sub new$/;" s
+new lib/Excel/Template/Container/Bold.pm /^sub new$/;" s
+new lib/Excel/Template/Container/Hidden.pm /^sub new$/;" s
+new lib/Excel/Template/Container/Italic.pm /^sub new$/;" s
+new lib/Excel/Template/Container/Locked.pm /^sub new$/;" s
+new lib/Excel/Template/Container/Loop.pm /^sub new$/;" s
+new lib/Excel/Template/Container/Outline.pm /^sub new$/;" s
+new lib/Excel/Template/Container/Shadow.pm /^sub new$/;" s
+new lib/Excel/Template/Container/Strikeout.pm /^sub new$/;" s
+new lib/Excel/Template/Context.pm /^sub new$/;" s
+new lib/Excel/Template/Element/Cell.pm /^sub new$/;" s
+new lib/Excel/Template/Iterator.pm /^sub new$/;" s
+new lib/Excel/Template/TextObject.pm /^sub new$/;" s
+new t/Spreadsheet/WriteExcel.pm /^sub new {$/;" s
+new t/Spreadsheet/WriteExcel/Big.pm /^sub new {$/;" s
+new t/Spreadsheet/WriteExcel/Worksheet.pm /^sub new {$/;" s
+new t/Spreadsheet/WriteExcelXML.pm /^sub new {$/;" s
+new_worksheet lib/Excel/Template/Context.pm /^sub new_worksheet$/;" s
+next lib/Excel/Template/Iterator.pm /^sub next$/;" s
+output lib/Excel/Template.pm /^sub output$/;" s
+param lib/Excel/Template.pm /^sub param$/;" s
+param lib/Excel/Template/Context.pm /^sub param$/;" s
+parse_xml lib/Excel/Template.pm /^sub parse_xml$/;" s
+register lib/Excel/Template.pm /^sub register { shift; Excel::Template::Factory->register(@_) }$/;" s
+register lib/Excel/Template/Factory.pm /^ sub register$/;" s
+render lib/Excel/Template/Base.pm /^sub render$/;" s
+render lib/Excel/Template/Container.pm /^sub render { $_[0]->iterate_over_children($_[1]) }$/;" s
+render lib/Excel/Template/Container/Conditional.pm /^sub render$/;" s
+render lib/Excel/Template/Container/Format.pm /^sub render$/;" s
+render lib/Excel/Template/Container/Loop.pm /^sub render$/;" s
+render lib/Excel/Template/Container/Row.pm /^sub render$/;" s
+render lib/Excel/Template/Container/Worksheet.pm /^sub render$/;" s
+render lib/Excel/Template/Element/Cell.pm /^sub render$/;" s
+render lib/Excel/Template/Element/Formula.pm /^sub render { $_[0]->SUPER::render( $_[1], 'write_formula' ) }$/;" s
+render t/Register_018.pm /^sub render$/;" s
+reset t/mock.pm /^sub reset { @calls = (); }$/;" s
+resolve lib/Excel/Template/Base.pm /^sub resolve$/;" s
+resolve lib/Excel/Template/Context.pm /^sub resolve$/;" s
+resolve lib/Excel/Template/Element/Backref.pm /^sub resolve$/;" s
+resolve lib/Excel/Template/Element/Range.pm /^sub resolve$/;" s
+resolve lib/Excel/Template/Element/Var.pm /^sub resolve { ($_[1])->param($_[1]->resolve($_[0], 'NAME')) }$/;" s
+resolve lib/Excel/Template/TextObject.pm /^sub resolve$/;" s
+set_column t/Spreadsheet/WriteExcel/Worksheet.pm /^sub set_column {$/;" s
+set_row t/Spreadsheet/WriteExcel/Worksheet.pm /^sub set_row {$/;" s
+use_unicode lib/Excel/Template/Context.pm /^sub use_unicode { $_[0]->{UNICODE} && 1 }$/;" s
+write t/Spreadsheet/WriteExcel/Worksheet.pm /^sub write {$/;" s
+write_blank t/Spreadsheet/WriteExcel/Worksheet.pm /^sub write_blank {$/;" s
+write_file lib/Excel/Template.pm /^sub write_file$/;" s
+write_formula t/Spreadsheet/WriteExcel/Worksheet.pm /^sub write_formula {$/;" s
+write_number t/Spreadsheet/WriteExcel/Worksheet.pm /^sub write_number {$/;" s
+write_string t/Spreadsheet/WriteExcel/Worksheet.pm /^sub write_string {$/;" s
+write_url t/Spreadsheet/WriteExcel/Worksheet.pm /^sub write_url {$/;" s