package Lire::Test::PluginTestCase;

use strict;

use base qw/ Lire::Test::TestCase /;

use Lire::Config::SpecParser;
use Lire::PluginManager;
use Lire::Utils qw/file_content/;
use Lire::ReportParser::AsciiDocBookFormatter qw/dbk2txt/;

=pod

=head1 NAME

Lire::Test::PluginTestCase - Base class for writing Plugin unit tests

=head1 SYNOPSIS

  use base qw/ Lire::Test::PluginTestCase /;

  use MyPlugin;
  use File::Basename;

  sub create_plugin {
    return new MyPlugin();
  }

  sub registration_file {
    return dirname( __FILE__ ) .  "../../plugin_init";
  }

=head1 DESCRIPTION

This is a Test::Unit::TestCase subclass which can be used to easily
write tests for Lire::Plugin. This class implements what is needed to
provide the necessary fixture in the set_up() and tear_down().

It provides two base tests: test_api() and test_registration_file().

The test class needs to implement two methods to help complete the
fixture.

=head1 FIXTURES

These are the methods that subclasses will usually override to provide
the necessary data so that the ChartType test fixtures be setup.

=head2 registration_file()

This should return the script that is responsible for registring the
analyser with the Lire::PluginManager. This is used by the default
test_registration_file().

=cut

sub registration_file {
    die "registration_file() unimplemented in ", ref $_[0], "\n";
}

=pod

=head2 properties_spec_file()

If this method returns a filename, it will be set as the default
configuration spec for the test. Use it when the plugin has properties.

=cut

sub properties_spec_file {
    return undef;
}

=pod

=head2 create_plugin()

This should return an instance of the Lire::Plugin instance to
test.

=cut

sub create_plugin {
    die "create_() unimplemented in ", ref $_[0], "\n";
}

sub set_up {
    my $self = $_[0];
    $self->SUPER::set_up();
    $self->set_up_plugin_mgr();

    my $spec_file = $self->properties_spec_file();
    if ( $spec_file ) {
        my $parser = new Lire::Config::SpecParser();
        $parser->merge_specification( $spec_file );
        $self->{'cfg'}{'_lr_config_spec'} = $parser->configspec();
    }

    return;
}

=pod

=head1 DEFAULT TESTS

=head2 test_api()

Make sure that all methods required by Lire::Plugin are
implemented.

It checks that description() formats correctly as DocBook.

=head2 test_registration_file()

Checks that the registration script correctly registers the
analyser with the PluginManager.

=cut

sub test_registration_file {
    my $self = $_[0];

    my $plugin = $self->create_plugin();
    $self->error( "$plugin should be a Lire::Plugin" )
      unless $plugin->isa( 'Lire::Plugin' );

    eval file_content( $self->registration_file() );
    $self->error( $@ ) if $@;

    $self->assert( Lire::PluginManager->has_plugin( $plugin->type(),
                                                    $plugin->name() ),
                   $plugin->name() . " wasn't registered" );
}

sub test_api {
    my $self = $_[0];

    my $plugin = $self->create_plugin();
    $self->error( "$plugin should be a Lire::Plugin" )
      unless $plugin->isa( 'Lire::Plugin' );

    $self->assert_not_null( $plugin->name(),
                            "name() returned undef" );
    $self->assert_not_null( $plugin->title(),
                            "title() returned undef" );

    my @warn = ();
    local $SIG{__WARN__} = sub { my $msg = join "", @_;
                                 push @warn, $msg;
                                 $self->annotate( $msg ) };
    $self->assert_not_null( $plugin->description(),
                            "description() returned undef" );
    eval { dbk2txt( $plugin->description() ) };
    $self->fail( "error while formatting description: $@" )
      if $@;

    $self->assert( ! @warn, "there were DocBook warnings" );
}

# keep perl happy
1;

__END__

=pod

=head1 SEE ALSO

Lire::Test::TestCase(3pm), Lire::Plugin(3pm)

=head1 AUTHOR

Francis J. Lacoste <flacoste@logreport.org>

=head1 VERSION

$Id: PluginTestCase.pm,v 1.2 2006/07/23 13:16:32 vanbaal Exp $

=head1 COPYRIGHT

Copyright (C) 2004 Stichting LogReport Foundation LogReport@LogReport.org

This file is part of Lire.

Lire is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program (see COPYING); if not, check with
http://www.gnu.org/copyleft/gpl.html.

=cut

