Revision history for Perl distribution Excel::Template
+0.16 Fri Nov 05 16:15:00 2004
+ - Fixed Makefile.PL so that it uses PM_FILTER instead of rolling its own
+ - This means that the Unicode handling is cleaner from a source
+ perspective
+ - Added MANIFEST.SKIP to skip /.svn/ and 'vi' .swp files during distcheck
+ - Finally have a semi-real testing suite!
+ - Added minimal Spreadsheet::WriteExcel mockobject
+ - Fixed several bugs in formats found by building tests
+ - HIDDEN node now actually works
+ - LOCKED node now actually works
+
0.15 Thu Nov 04 16:15:00 2004
- - Fixed bugs that were:
- - preventing a worksheet from using a variable name in a loop
- - allowing two worksheets to have the same name
- - preventing a worksheet from being called '0' or '0.0'
- - Added back-references. This allows for one cell to refer to another
- cell in an Excel-aware way, especially in formulas.
- - Added the following nodes:
- - BACKREF
- - RANGE
+ - Fixed bugs that were:
+ - preventing a worksheet from using a variable name in a loop
+ - allowing two worksheets to have the same name
+ - preventing a worksheet from being called '0' or '0.0'
+ - Added back-references. This allows for one cell to refer to another
+ cell in an Excel-aware way, especially in formulas.
+ - Added the following nodes:
+ - BACKREF
+ - RANGE
0.14 Thu Nov 04 13:30:00 2004
- - Added new format support for (nearly) all formats supported by
- Spreadsheet::WriteExcel
- - Fixed email address everywhere
+ - Added new format support for (nearly) all formats supported by
+ Spreadsheet::WriteExcel
+ - Fixed email address everywhere
0.13 Thu Oct 29 07:30:00 2004
- - Fixed email address and added GoogleGroup
+ - Fixed email address and added GoogleGroup
0.12 Thu Apr 08 07:30:00 2004
- - Fixed bug regarding empty arrays as loop variables
+ - Fixed bug regarding empty arrays as loop variables
0.11 Wed Mar 17 16:00:00 2004
- - Fixed bug introduced in 0.10 (Loops were not case-insensitive)
+ - Fixed bug introduced in 0.10 (Loops were not case-insensitive)
0.10 Wed Mar 17 16:00:00 2004
- - Parameters are now case-insensitive
+ - Parameters are now case-insensitive
0.09 Mon Feb 02 16:00:00 2004
- - Fixed bug with multiple worksheets
+ - Fixed bug with multiple worksheets
0.08 Fri Jan 30 14:00:00 2004
- - Added Base to the params for XML::Parser to allow for entity includes
+ - Added Base to the params for XML::Parser to allow for entity includes
0.07 Fri Jan 23 08:30:00 2004
- - Fixed the MANIFEST to account for missing files
+ - Fixed the MANIFEST to account for missing files
0.06 Mon Jan 20 11:00:00 2004
- - Added formulas (no back-references yet)
- - Improved POD a little
+ - Added formulas (no back-references yet)
+ - Improved POD a little
0.05 Wed Jan 16 12:30:00 2004
- - Fixed a bug in formats
+ - Fixed a bug in formats
0.04 Wed Jan 16 12:00:00 2004
- - Added BIG_FILES as an option, which will use
- Spreadsheet::WriteExcel::Big as the renderer (yet unimplemented)
- - Changed the output() method to use a tied IO::Scalar (which is
- now a requirement.
- - Firmed up the infrastructure in Excel::Template::Format
- - Added the following tags
- - FORMAT
- - HIDDEN
- - LOCKED
- - OUTLINE
- - SHADOW
- - STRIKEOUT
+ - Added BIG_FILES as an option, which will use
+ Spreadsheet::WriteExcel::Big as the renderer (yet unimplemented)
+ - Changed the output() method to use a tied IO::Scalar (which is
+ now a requirement.
+ - Firmed up the infrastructure in Excel::Template::Format
+ - Added the following tags
+ - FORMAT
+ - HIDDEN
+ - LOCKED
+ - OUTLINE
+ - SHADOW
+ - STRIKEOUT
0.03 Wed Dec 03 20:30:00 2003
- - Added XML::Parser as a required pre-requisite module
- - Added Italic format
- - Removed $VERSION from Excel::Template::Base (Unneeded)
- - No documentation or testing changes
+ - Added XML::Parser as a required pre-requisite module
+ - Added Italic format
+ - Removed $VERSION from Excel::Template::Base (Unneeded)
+ - No documentation or testing changes
0.02 Sun Nov 30 17:00:00 2003
- - documentation improvements
- - No actual functional changes
+ - documentation improvements
+ - No actual functional changes
0.01 Tue Nov 18 14:23:42 2003
- - original version; created by ExtUtils::ModuleMaker 0.32
-
-
+ - original version; created by ExtUtils::ModuleMaker 0.32
MANIFEST
+MANIFEST.SKIP
LICENSE
README
Todo
lib/Excel/Template/Factory.pm
lib/Excel/Template/Format.pm
lib/Excel/Template/Iterator.pm
-lib/Excel/Template/TextObject.pm_
+lib/Excel/Template/TextObject.pm
lib/Excel/Template/Container/Bold.pm
lib/Excel/Template/Container/Conditional.pm
lib/Excel/Template/Container/Format.pm
lib/Excel/Template/Container/Workbook.pm
lib/Excel/Template/Container/Worksheet.pm
lib/Excel/Template/Element/Backref.pm
-lib/Excel/Template/Element/Cell.pm_
+lib/Excel/Template/Element/Cell.pm
lib/Excel/Template/Element/Formula.pm
lib/Excel/Template/Element/Range.pm
lib/Excel/Template/Element/Var.pm
t/001_load.t
+t/002_workbook.t
+t/002.xml
+t/003_worksheet.t
+t/003.xml
+t/004_cell.t
+t/004.xml
+t/005_formats.t
+t/005.xml
+t/006_variables.t
+t/006.xml
+t/007_cell_formats.t
+t/007.xml
+t/008_formula.t
+t/008.xml
+t/mock.pm
+t/Spreadsheet/WriteExcel.pm
+t/Spreadsheet/WriteExcel/Worksheet.pm
Makefile.PL
META.yml Module meta-data (added by MakeMaker)
--- /dev/null
+\bRCS\b
+\bCVS\b
+,v$
+\B\.svn\b
+
+# Makemaker generated files and dirs.
+^MANIFEST\.
+^Makefile$
+^pm_to_blib$
+^blib/
+^MakeMaker-\d
+
+# Temp, old and emacs backup files.
+~$
+\.old$
+^#.*#$
+^\.#
+.swp$
--- /dev/null
+# http://module-build.sourceforge.net/META-spec.html
+#XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX#
+name: Excel-Template
+version: 0.15
+version_from: lib/Excel/Template.pm
+installdirs: site
+requires:
+ File::Basename: 0.01
+ IO::File: 0.01
+ IO::Scalar: 0.01
+ Spreadsheet::WriteExcel: 0.42
+ Test::Simple: 0.44
+ XML::Parser: 0.01
+
+distribution_type: module
+generated_by: ExtUtils::MakeMaker version 6.17
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
-use File::Spec;
+use strict;
my $prereqs = {
'Test::Simple' => 0.44,
+ 'Spreadsheet::WriteExcel' => 0.42,
'XML::Parser' => 0.01,
- 'IO::File' => 0.01,
'IO::Scalar' => 0.01,
'File::Basename' => 0.01,
- 'Spreadsheet::WriteExcel' => 0.42,
};
-# The assumption is the 5.8.0 and greater doesn't need Unicode::String.
+# The assumption is Perl 5.8.0 and greater doesn't need Unicode::String.
+
+my $use_unicode = 0;
if ($] < 5.008)
{
print "Do you want Unicode support? ";
my $answer = <STDIN>;
my $need_unicode = $answer =~ /^[Yy]/;
- my $use_unicode = 0;
if ($need_unicode)
{
- $prereqs{'Unicode::String'} = '0.01';
+ $prereqs->{'Unicode::String'} = '0.01';
$use_unicode = 1;
}
}
-use_unicode($use_unicode);
+my $pm_filter = $use_unicode
+ ? 'perl -p -e "s!UNI_YES ! !g;s!UNI_NO !\\#!g"'
+ : 'perl -p -e "s!UNI_NO ! !g;s!UNI_YES !\\#!g"';
WriteMakefile(
NAME => 'Excel::Template',
AUTHOR => 'Rob Kinyon (rob.kinyon@gmail.com)',
ABSTRACT => 'Excel::Template',
PREREQ_PM => $prereqs,
+ PM_FILTER => $pm_filter,
);
-
-sub use_unicode
-{
- my $using_unicode = shift;
-
- my @filenames = map {
- File::Spec->catfile(
- qw( lib Excel Template ),
- @{$_},
- )
- } ( [ qw( Element Cell.pm_ ) ], [ qw( TextObject.pm_ ) ] );
-
- foreach my $filename (@filenames)
- {
- open(IN_FILE, $filename)
- or die "Cannot open '$filename' for reading: $!\n";
- my @lines = <IN_FILE>;
- close(IN_FILE);
-
- if ($using_unicode)
- {
- for (@lines)
- {
- s/^UNI_YES / /;
- s/^UNI_NO /#/;
- }
- }
- else
- {
- for (@lines)
- {
- s/^UNI_YES /#/;
- s/^UNI_NO / /;
- }
- }
-
- $filename =~ s/_$//;
- open(OUT_FILE, ">$filename")
- or die "Cannot open '$filename' for writing: $!\n";
- print OUT_FILE @lines;
- close(OUT_FILE);
- }
-
- return 1;
-}
-TODO list for Perl module Excel::Template
+TODO list for Perl distribution Excel::Template
-- Add more formatting options, such as italic
-- Add fonts
-- Add numeric/string formats
-- Figure out how to add support for formulas, especially in <LOOP>s
- Figure out if and how to add support for charts
+- Add tests for LOOP, SCOPE, CONDITIONAL, BACKREF, and RANGE
+- Add more stringent tests for what we already have
- Anything else people suggest
-
use Excel::Template::Base;
use vars qw ($VERSION @ISA);
- $VERSION = '0.15';
+ $VERSION = '0.16';
@ISA = qw( Excel::Template::Base );
}
use File::Basename;
use XML::Parser;
-use IO::File;
use IO::Scalar;
sub new
$params{uc $_} = delete $params{$_} for keys %params;
@{$self->{PARAM_MAP}}{keys %params} = @params{keys %params};
- return 1;
+ return !!1;
}
sub write_file
$xls->close;
- return 1;
+ return !!1;
}
sub output
return $output;
}
-sub parse
-{
- my $self = shift;
-
- $self->parse_xml(@_);
-}
-
sub parse_xml
{
my $self = shift;
);
{
- my $fh = IO::File->new($fname)
+ open( INFILE, "<$fname" )
|| die "Cannot open '$fname' for reading: $!\n";
- $parser->parse(do { local $/ = undef; <$fh> });
+ $parser->parse(do { local $/ = undef; <INFILE> });
- $fh->close;
+ close INFILE;
}
- return 1;
+ return !!1;
}
+*parse = \&parse_xml;
sub _prepare_output
{
$_->render($context) for @{$self->{WORKBOOKS}};
- return 1;
+ return !!1;
}
sub register { shift; Excel::Template::Factory::register(@_) }
=head1 NODE NAME
-REF
+BACKREF
=head1 INHERITANCE
--- /dev/null
+package Excel::Template::Element::Cell;
+
+use strict;
+
+BEGIN {
+ use vars qw(@ISA);
+ @ISA = qw(Excel::Template::Element);
+
+ use Excel::Template::Element;
+}
+
+sub new
+{
+ my $class = shift;
+ my $self = $class->SUPER::new(@_);
+
+ $self->{TXTOBJ} = Excel::Template::Factory->create('TEXTOBJECT');
+
+ return $self;
+}
+
+sub get_text
+{
+ my $self = shift;
+ my ($context) = @_;
+
+ my $txt = $context->get($self, 'TEXT');
+ if (defined $txt)
+ {
+ my $txt_obj = Excel::Template::Factory->create('TEXTOBJECT');
+ push @{$txt_obj->{STACK}}, $txt;
+ $txt = $txt_obj->resolve($context);
+ }
+ elsif ($self->{TXTOBJ})
+ {
+ $txt = $self->{TXTOBJ}->resolve($context)
+ }
+ else
+ {
+UNI_YES $txt = Unicode::String::utf8('');
+UNI_NO $txt = '';
+ }
+
+ return $txt;
+}
+
+sub render
+{
+ my $self = shift;
+ my ($context, $method) = @_;
+
+ $method ||= 'write';
+
+ my ($row, $col) = map { $context->get($self, $_) } qw(ROW COL);
+
+ my $ref = uc $context->get( $self, 'REF' );
+ if (defined $ref && length $ref)
+ {
+ $context->add_reference( $ref, $row, $col );
+ }
+
+ $context->active_worksheet->$method(
+ $row, $col,
+ $self->get_text($context),
+ $context->active_format,
+ );
+
+ return 1;
+}
+
+sub deltas
+{
+ return {
+ COL => +1,
+ };
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Excel::Template::Element::Cell - Excel::Template::Element::Cell
+
+=head1 PURPOSE
+
+To actually write stuff to the worksheet
+
+=head1 NODE NAME
+
+CELL
+
+=head1 INHERITANCE
+
+Excel::Template::Element
+
+=head1 ATTRIBUTES
+
+=over 4
+
+=item * TEXT
+
+This is the text to write to the cell. This can either be text or a parameter
+with a dollar-sign in front of the parameter name.
+
+=item * COL
+
+Optionally, you can specify which column you want this cell to be in. It can be
+either a number (zero-based) or an offset. See Excel::Template for more info on
+offset-based numbering.
+
+=item * REF
+
+Adds the current cell to the a list of cells that can be backreferenced.
+This is useful when the current cell needs to be referenced by a
+formula. See BACKREF and RANGE.
+
+=back 4
+
+There will be more parameters added, as features are added.
+
+=head1 CHILDREN
+
+Excel::Template::Element::Formula
+
+=head1 EFFECTS
+
+This will consume one column on the current row.
+
+=head1 DEPENDENCIES
+
+None
+
+=head1 USAGE
+
+ <cell text="Some Text Here"/>
+ <cell>Some other text here</cell>
+
+ <cell text="$Param2"/>
+ <cell>Some <var name="Param"> text here</cell>
+
+In the above example, four cells are written out. The first two have text hard-
+coded. The second two have variables. The third and fourth items have another
+thing that should be noted. If you have text where you want a variable in the
+middle, you have to use the latter form. Variables within parameters are the
+entire parameter's value.
+
+Please see Spreadsheet::WriteExcel for what constitutes a legal formula.
+
+=head1 AUTHOR
+
+Rob Kinyon (rob.kinyon@gmail.com)
+
+=head1 SEE ALSO
+
+ROW, VAR, FORMULA
+
+=cut
use Excel::Template::Element::Cell;
}
-sub get_text
-{
- my $self = shift;
- my ($context) = @_;
-
- my $text = $self->SUPER::get_text($context);
-
-# At this point, we must do back-reference dereferencing
-
- return $text;
-}
-
-sub render
-{
- my $self = shift;
- my ($context) = @_;
-
- $context->active_worksheet->write_formula(
- (map { $context->get($self, $_) } qw(ROW COL)),
- $self->get_text($context),
- );
-
- return 1;
-}
+sub render { $_[0]->SUPER::render( $_[1], 'write_formula' ) }
+#{
+# my $self = shift;
+# my ($context) = @_;
+#
+# return $self->SUPER::render( $context, 'write_formula' );
+#}
1;
__END__
=head1 ATTRIBUTES
-=over 4
-
-=item * TEXT
-
-This is the formula to write to the cell. This can either be text or a parameter
-with a dollar-sign in front of the parameter name.
-
-=item * COL
-
-Optionally, you can specify which column you want this cell to be in. It can be
-either a number (zero-based) or an offset. See Excel::Template for more info on
-offset-based numbering.
-
-=back 4
-
-There will be more parameters added, as features are added.
+All attributes a CELL can have, a FORMULA can have, including the ability to be
+referenced using the 'ref' attribute.
=head1 CHILDREN
=head1 SEE ALSO
-ROW, VAR, CELL
+CELL
=cut
=head1 PURPOSE
-Returns a range of cell locations (i.e. B2:C2) that contains all calls using this
-reference. To return the location of the last cell, use REF.
+Returns a range of cell locations (i.e. B2:C2) that contains all calls using
+this reference. To return the location of the last cell, use BACKREF.
=head1 NODE NAME
-REF
+RANGE
=head1 INHERITANCE
=head1 SEE ALSO
-CELL, REF
+CELL, BACKREF
=cut
FORMAT
FORMULA
IF
+ HIDDEN
ITALIC
+ LOCKED
OUTLINE
LOOP
BACKREF
for grep { $boolean_parts[$_] } 0 .. $#_boolean_formats;
$params{ $_integer_formats[$_] } = $integer_parts[$_]
- for grep { length $integer_parts[$_] } 0 .. $#_integer_formats;
+ for grep { defined $integer_parts[$_] } 0 .. $#_integer_formats;
$params{ $_string_formats[$_] } = $string_parts[$_]
for grep { $string_parts[$_] } 0 .. $#_string_formats;
shift;
my ($context, $old_fmt, %properties) = @_;
+ # This is a key used for non-format book-keeping.
+ delete $properties{ ELEMENTS };
+
defined(my $key = _retrieve_key($old_fmt))
|| die "Internal Error: Cannot find key for format '$old_fmt'!\n";
next PROPERTY;
}
}
+
+ warn "Property '$prop' is unrecognized\n";
}
my $new_key = _params_to_key(%params);
--- /dev/null
+package Excel::Template::TextObject;
+
+use strict;
+
+BEGIN {
+ use vars qw(@ISA);
+ @ISA = qw(Excel::Template::Base);
+
+ use Excel::Template::Base;
+
+UNI_YES use Unicode::String;
+}
+
+# This is a helper object. It is not instantiated by the user,
+# nor does it represent an XML object. Rather, certain elements,
+# such as <textbox>, can use this object to do text with variable
+# substitutions.
+
+sub new
+{
+ my $class = shift;
+ my $self = $class->SUPER::new(@_);
+
+ $self->{STACK} = [] unless UNIVERSAL::isa($self->{STACK}, 'ARRAY');
+
+ return $self;
+}
+
+sub resolve
+{
+ my $self = shift;
+ my ($context) = @_;
+
+UNI_YES my $t = Unicode::String::utf8('');
+UNI_NO my $t = '';
+
+ for my $tok (@{$self->{STACK}})
+ {
+ my $val = $tok;
+ $val = $val->resolve($context)
+ if Excel::Template::Factory::is_embedded( $val );
+
+UNI_YES $t .= Unicode::String::utf8("$val");
+UNI_NO $t .= $val;
+ }
+
+ return $t;
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Excel::Template::TextObject
+
+=head1 PURPOSE
+
+=head1 NODE NAME
+
+=head1 INHERITANCE
+
+=head1 ATTRIBUTES
+
+=head1 CHILDREN
+
+=head1 AFFECTS
+
+=head1 DEPENDENCIES
+
+=head1 USAGE
+
+=head1 AUTHOR
+
+Rob Kinyon (rob.kinyon@gmail.com)
+
+=head1 SEE ALSO
+
+=cut
-# -*- perl -*-
-
-# t/001_load.t - check module loading and create testing directory
+use strict;
+use warnings;
+$|++;
use Test::More tests => 2;
-BEGIN { use_ok( 'Excel::Template' ); }
+my $CLASS = 'Excel::Template';
+
+use_ok( $CLASS );
-my $object = Excel::Template->new ();
-isa_ok ($object, 'Excel::Template');
+my $object = $CLASS->new ();
+isa_ok( $object, $CLASS );
--- /dev/null
+<workbook />
--- /dev/null
+use strict;
+use warnings;
+$|++;
+
+use Test::More tests => 4;
+
+use lib 't';
+use mock;
+mock->reset;
+
+my $CLASS = 'Excel::Template';
+use_ok( $CLASS );
+
+my $object = $CLASS->new(
+ filename => 't/002.xml',
+);
+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::close( '' )
+__END_EXPECTED__
--- /dev/null
+<workbook>
+ <worksheet />
+ <worksheet name="foo"/>
+ <worksheet name="foo"/>
+</workbook>
--- /dev/null
+use strict;
+use warnings;
+$|++;
+
+use Test::More tests => 4;
+
+use lib 't';
+use mock;
+mock->reset;
+
+my $CLASS = 'Excel::Template';
+use_ok( $CLASS );
+
+my $object = $CLASS->new(
+ filename => 't/003.xml',
+);
+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( '' )
+Spreadsheet::WriteExcel::Worksheet::new( '' )
+Spreadsheet::WriteExcel::add_worksheet( 'foo' )
+Spreadsheet::WriteExcel::Worksheet::new( '' )
+Spreadsheet::WriteExcel::add_worksheet( '' )
+Spreadsheet::WriteExcel::Worksheet::new( '' )
+Spreadsheet::WriteExcel::close( '' )
+__END_EXPECTED__
--- /dev/null
+<workbook>
+ <worksheet name="cell">
+ <cell>Test1</cell>
+ <cell text="Test2" />
+ <cell />
+ </worksheet>
+</workbook>
--- /dev/null
+use strict;
+use warnings;
+$|++;
+
+use Test::More tests => 4;
+
+use lib 't';
+use mock;
+mock->reset;
+
+my $CLASS = 'Excel::Template';
+use_ok( $CLASS );
+
+my $object = $CLASS->new(
+ filename => 't/004.xml',
+);
+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( 'cell' )
+Spreadsheet::WriteExcel::Worksheet::new( '' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '0', 'Test1', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '1', 'Test2', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '2', '', '1' )
+Spreadsheet::WriteExcel::close( '' )
+__END_EXPECTED__
--- /dev/null
+<workbook>
+ <bold />
+ <hidden />
+ <italic />
+ <locked />
+ <shadow />
+ <strikeout />
+
+ <format font_outline="1" />
+ <format shrink="1" />
+ <format text_wrap="1" />
+ <format text_justlast="1" />
+ <format size="3" />
+ <format num_format="3" />
+ <format underline="3" />
+ <format rotation="3" />
+ <format indent="3" />
+ <format pattern="3" />
+ <format border="3" />
+ <format bottom="3" />
+ <format top="3" />
+ <format left="3" />
+ <format right="3" />
+ <format font="3" />
+ <format color="3" />
+ <format align="3" />
+ <format valign="3" />
+ <format bg_color="3" />
+ <format fg_color="3" />
+ <format border_color="3" />
+ <format bottom_color="3" />
+ <format top_color="3" />
+ <format left_color="3" />
+ <format right_color="3" />
+
+
+ <bold><italic><hidden /></italic></bold>
+</workbook>
--- /dev/null
+use strict;
+use warnings;
+$|++;
+
+use Test::More tests => 4;
+
+use lib 't';
+use mock;
+mock->reset;
+
+my $CLASS = 'Excel::Template';
+use_ok( $CLASS );
+
+my $object = $CLASS->new(
+ filename => 't/005.xml',
+);
+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_format( 'bold', '1' )
+Spreadsheet::WriteExcel::add_format( 'hidden', '1' )
+Spreadsheet::WriteExcel::add_format( 'italic', '1' )
+Spreadsheet::WriteExcel::add_format( 'locked', '1' )
+Spreadsheet::WriteExcel::add_format( 'font_shadow', '1' )
+Spreadsheet::WriteExcel::add_format( 'font_strikeout', '1' )
+Spreadsheet::WriteExcel::add_format( 'font_outline', '1' )
+Spreadsheet::WriteExcel::add_format( 'shrink', '1' )
+Spreadsheet::WriteExcel::add_format( 'text_wrap', '1' )
+Spreadsheet::WriteExcel::add_format( 'text_justlast', '1' )
+Spreadsheet::WriteExcel::add_format( 'size', '3' )
+Spreadsheet::WriteExcel::add_format( 'num_format', '3' )
+Spreadsheet::WriteExcel::add_format( 'underline', '3' )
+Spreadsheet::WriteExcel::add_format( 'rotation', '3' )
+Spreadsheet::WriteExcel::add_format( 'indent', '3' )
+Spreadsheet::WriteExcel::add_format( 'pattern', '3' )
+Spreadsheet::WriteExcel::add_format( 'border', '3' )
+Spreadsheet::WriteExcel::add_format( 'bottom', '3' )
+Spreadsheet::WriteExcel::add_format( 'top', '3' )
+Spreadsheet::WriteExcel::add_format( 'left', '3' )
+Spreadsheet::WriteExcel::add_format( 'right', '3' )
+Spreadsheet::WriteExcel::add_format( 'font', '3' )
+Spreadsheet::WriteExcel::add_format( 'color', '3' )
+Spreadsheet::WriteExcel::add_format( 'align', '3' )
+Spreadsheet::WriteExcel::add_format( 'valign', '3' )
+Spreadsheet::WriteExcel::add_format( 'bg_color', '3' )
+Spreadsheet::WriteExcel::add_format( 'fg_color', '3' )
+Spreadsheet::WriteExcel::add_format( 'border_color', '3' )
+Spreadsheet::WriteExcel::add_format( 'bottom_color', '3' )
+Spreadsheet::WriteExcel::add_format( 'top_color', '3' )
+Spreadsheet::WriteExcel::add_format( 'left_color', '3' )
+Spreadsheet::WriteExcel::add_format( 'right_color', '3' )
+Spreadsheet::WriteExcel::add_format( 'bold', '1', 'italic', '1' )
+Spreadsheet::WriteExcel::add_format( 'bold', '1', 'hidden', '1', 'italic', '1' )
+Spreadsheet::WriteExcel::close( '' )
+__END_EXPECTED__
--- /dev/null
+<workbook>
+ <worksheet name="cell">
+ <cell><var name="test1" /></cell>
+ <cell text="$test2" />
+ <cell>PRE <var name="test1" /> POST</cell>
+ </worksheet>
+</workbook>
--- /dev/null
+use strict;
+use warnings;
+$|++;
+
+use Test::More tests => 5;
+
+use lib 't';
+use mock;
+mock->reset;
+
+my $CLASS = 'Excel::Template';
+use_ok( $CLASS );
+
+my $object = $CLASS->new(
+ filename => 't/006.xml',
+);
+isa_ok( $object, $CLASS );
+
+ok(
+ $object->param(
+ test1 => 'test1',
+ test2 => 'test2',
+ ),
+ 'Parameters set',
+);
+
+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( 'cell' )
+Spreadsheet::WriteExcel::Worksheet::new( '' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '0', 'test1', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '1', 'test2', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '2', 'PRE test1 POST', '1' )
+Spreadsheet::WriteExcel::close( '' )
+__END_EXPECTED__
--- /dev/null
+<workbook>
+ <worksheet name="cell">
+ <cell />
+ <bold>
+ <cell />
+ <italic>
+ <cell />
+ </italic>
+ </bold>
+ </worksheet>
+</workbook>
--- /dev/null
+use strict;
+use warnings;
+$|++;
+
+use Test::More tests => 4;
+
+use lib 't';
+use mock;
+mock->reset;
+
+my $CLASS = 'Excel::Template';
+use_ok( $CLASS );
+
+my $object = $CLASS->new(
+ filename => 't/007.xml',
+);
+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( 'cell' )
+Spreadsheet::WriteExcel::Worksheet::new( '' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '0', '', '1' )
+Spreadsheet::WriteExcel::add_format( 'bold', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '1', '', '2' )
+Spreadsheet::WriteExcel::add_format( 'bold', '1', 'italic', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '2', '', '3' )
+Spreadsheet::WriteExcel::close( '' )
+__END_EXPECTED__
--- /dev/null
+<workbook>
+ <worksheet name="formula">
+ <formula>Test1</formula>
+ <formula text="Test2" />
+ <formula />
+ </worksheet>
+</workbook>
--- /dev/null
+use strict;
+use warnings;
+$|++;
+
+use Test::More tests => 4;
+
+use lib 't';
+use mock;
+mock->reset;
+
+my $CLASS = 'Excel::Template';
+use_ok( $CLASS );
+
+my $object = $CLASS->new(
+ filename => 't/008.xml',
+);
+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( 'formula' )
+Spreadsheet::WriteExcel::Worksheet::new( '' )
+Spreadsheet::WriteExcel::Worksheet::write_formula( '0', '0', 'Test1', '1' )
+Spreadsheet::WriteExcel::Worksheet::write_formula( '0', '1', 'Test2', '1' )
+Spreadsheet::WriteExcel::Worksheet::write_formula( '0', '2', '', '1' )
+Spreadsheet::WriteExcel::close( '' )
+__END_EXPECTED__
--- /dev/null
+package Spreadsheet::WriteExcel;
+
+use strict;
+
+use mock;
+use Spreadsheet::WriteExcel::Worksheet;
+
+sub new {
+ my $self = bless {
+ }, shift;
+
+ {
+ local $" = "', '";
+ push @mock::calls, __PACKAGE__ . "::new( '@_' )";
+ }
+
+ return $self;
+}
+
+sub close {
+ shift;
+ {
+ local $" = "', '";
+ push @mock::calls, __PACKAGE__ . "::close( '@_' )";
+ }
+}
+
+sub add_worksheet {
+ shift;
+ {
+ local $" = "', '";
+ push @mock::calls, __PACKAGE__ . "::add_worksheet( '@_' )";
+ }
+ return Spreadsheet::WriteExcel::Worksheet->new;
+}
+
+my $format_num = 1;
+sub add_format {
+ shift;
+ my %x = @_;
+ my @x = map { $_ => $x{$_} } sort keys %x;
+ {
+ local $" = "', '";
+ push @mock::calls, __PACKAGE__ . "::add_format( '@x' )";
+ }
+ return $format_num++;
+}
+
+1;
+__END__
--- /dev/null
+package Spreadsheet::WriteExcel::Worksheet;
+
+use strict;
+
+use mock;
+
+sub new {
+ my $self = bless {
+ }, shift;
+
+ {
+ local $" = "', '";
+ push @mock::calls, __PACKAGE__ . "::new( '@_' )";
+ }
+
+ return $self;
+}
+
+sub write_formula {
+ my $self = shift;
+
+ {
+ local $" = "', '";
+ push @mock::calls, __PACKAGE__ . "::write_formula( '@_' )";
+ }
+}
+
+sub write {
+ my $self = shift;
+
+ {
+ local $" = "', '";
+ push @mock::calls, __PACKAGE__ . "::write( '@_' )";
+ }
+}
+
+1;
+__END__
--- /dev/null
+package mock;
+
+use strict;
+
+use vars qw/ @calls /;
+
+@calls = ();
+
+sub reset { @calls = (); }
+sub get_calls { @calls }
+
+
+1;
+__END__