From: Tara L Andrews Date: Thu, 13 Sep 2012 14:40:17 +0000 (+0200) Subject: split off stemma analysis modules from base Tradition layer X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=951ddfe8781b6111653ed8074488e5ddb65178f7;p=scpubgit%2Fstemmatology.git split off stemma analysis modules from base Tradition layer --- diff --git a/.gitignore b/.gitignore index 484a79c..b00040d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,22 @@ *~ -*.bbprojectd/ -t/var +*/t/var data -!/t/data +!*/t/data Makefile Makefile.old META.yml blib db inc +blib/ +.build/ +_build/ +cover_db/ +inc/ +Build +Build.bat +.last_cover_stats +MANIFEST.bak +MYMETA.yml +nytprof.out +pm_to_blib diff --git a/MANIFEST.SKIP b/MANIFEST.SKIP deleted file mode 100644 index 441a8fe..0000000 --- a/MANIFEST.SKIP +++ /dev/null @@ -1,11 +0,0 @@ -lib/Text/Tradition/Parser/BaseText.pm -lib/Text/Tradition/Parser/CollateText.pm -lib/Text/Tradition/Parser/CTE.pm -lib/Text/Tradition/Parser/KUL.pm -lib/Text/Tradition/Analysis.pm -lib/Text/Tradition/Analysis/Result.pm -t/analysis.t -t/text_tradition_analysis.t -t/text_tradition_analysis_result.t -.git/ -.gitignore diff --git a/analysis/Makefile.PL b/analysis/Makefile.PL new file mode 100644 index 0000000..62d8e49 --- /dev/null +++ b/analysis/Makefile.PL @@ -0,0 +1,26 @@ +#!/usr/bin/env perl + +use inc::Module::Install; +author( 'Tara L Andrews ' ); +license( 'perl' ); +perl_version( '5.012' ); +all_from( 'lib/Text/Tradition/Analysis.pm' ); +requires( 'Algorithm::Diff' ); +requires( 'Bio::Phylo::IO' ); +requires( 'File::chdir' ); +requires( 'File::Which' ); +requires( 'Graph' ); +requires( 'Graph::Reader::Dot' ); +requires( 'IPC::Run' ); +requires( 'JSON' ); +requires( 'LWP::UserAgent' ); +requires( 'Moose' ); +requires( 'Moose::Role' ); +requires( 'Set::Scalar' ); +requires( 'Text::Tradition' ); +requires( 'Text::Tradition::Directory' ); +requires( 'Text::Tradition::Error' ); +requires( 'TryCatch' ); + +build_requires( 'Test::More::UTF8' ); +&WriteAll; diff --git a/lib/Text/Tradition/Analysis.pm b/analysis/lib/Text/Tradition/Analysis.pm similarity index 97% rename from lib/Text/Tradition/Analysis.pm rename to analysis/lib/Text/Tradition/Analysis.pm index e1a69cd..3b76ca1 100644 --- a/lib/Text/Tradition/Analysis.pm +++ b/analysis/lib/Text/Tradition/Analysis.pm @@ -14,8 +14,10 @@ use Text::Tradition::Directory; use Text::Tradition::Stemma; use TryCatch; -use vars qw/ @EXPORT_OK /; +use vars qw/ @EXPORT_OK $VERSION /; @EXPORT_OK = qw/ run_analysis group_variants analyze_variant_location wit_stringify /; +$VERSION = "1.0"; + my $SOLVER_URL = 'http://byzantini.st/cgi-bin/graphcalc.cgi'; my $unsolved_problems = {}; @@ -32,6 +34,7 @@ Text::Tradition::Analysis - functions for stemma analysis of a tradition 'name' => 'this is a text', 'input' => 'TEI', 'file' => '/path/to/tei_parallel_seg_file.xml' ); + $t->enable_stemmata; $t->add_stemma( 'dotfile' => $stemmafile ); my $variant_data = run_analysis( $tradition ); @@ -41,9 +44,18 @@ Text::Tradition::Analysis - functions for stemma analysis of a tradition =head1 DESCRIPTION Text::Tradition is a library for representation and analysis of collated -texts, particularly medieval ones. The Collation is the central feature of -a Tradition, where the text, its sequence of readings, and its relationships -between readings are actually kept. +texts, particularly medieval ones. Where the Collation is the central feature of +a Tradition, it may also have one or more temmata associated with it, and these stemmata may be analyzed. This package provides the following modules: + +=over 4 + +=item * L - a role that can be composed into Text::Tradition objects, providing the ability for Text::Tradition::Stemma objects to be associated with them. + +=item * L - an object class that represents stemma hypotheses, both rooted (with a single archetype) and unrooted (e.g. phylogenetic trees). + +=item * Text::Tradition::Analysis (this package). Provides functions for the analysis of a given stemma against the collation within a given Tradition. + +=back =head1 SUBROUTINES @@ -75,6 +87,7 @@ my $datafile = 't/data/florilegium_tei_ps.xml'; my $tradition = Text::Tradition->new( 'input' => 'TEI', 'name' => 'test0', 'file' => $datafile ); +$tradition->enable_stemmata; my $s = $tradition->add_stemma( 'dotfile' => 't/data/florilegium.dot' ); is( ref( $s ), 'Text::Tradition::Stemma', "Added stemma to tradition" ); diff --git a/lib/Text/Tradition/Analysis/Result.pm b/analysis/lib/Text/Tradition/Analysis/Result.pm similarity index 99% rename from lib/Text/Tradition/Analysis/Result.pm rename to analysis/lib/Text/Tradition/Analysis/Result.pm index da1e123..2e920ff 100644 --- a/lib/Text/Tradition/Analysis/Result.pm +++ b/analysis/lib/Text/Tradition/Analysis/Result.pm @@ -88,6 +88,7 @@ my $datafile = 't/data/florilegium_tei_ps.xml'; my $tradition = Text::Tradition->new( 'input' => 'TEI', 'name' => 'flortest', 'file' => $datafile ); +$tradition->enable_stemmata; my $s = $tradition->add_stemma( 'dotfile' => 't/data/florilegium.dot' ); my $sets = [ [ qw/ D Q / ], [ qw/ F H / ], [ qw/ A B C P S T / ] ]; diff --git a/analysis/lib/Text/Tradition/HasStemma.pm b/analysis/lib/Text/Tradition/HasStemma.pm new file mode 100644 index 0000000..c797fab --- /dev/null +++ b/analysis/lib/Text/Tradition/HasStemma.pm @@ -0,0 +1,105 @@ +package Text::Tradition::HasStemma; + +use strict; +use warnings; +use Moose::Role; +use Text::Tradition::Stemma; + +=head1 NAME + +Text::Tradition::HasStemma - add-on to associate stemma hypotheses to Text::Tradition objects + +=head1 DESCRIPTION + +It is often the case that, for a given text tradition, the order of copying of the witnesses can or should be reconstructed (or at least the attempt should be made.) This class is a role that can be applied to Text::Tradition objects to record stemma hypotheses. See the documentation for L for more information. + +=head1 METHODS + +=head2 stemmata + +Return a list of all stemmata associated with the tradition. + +=head2 stemma_count + +Return the number of stemma hypotheses defined for this tradition. + +=head2 stemma( $idx ) + +Return the L object identified by the given index. + +=head2 clear_stemmata + +Delete all stemma hypotheses associated with this tradition. + +=cut + +has 'stemmata' => ( + traits => ['Array'], + isa => 'ArrayRef[Text::Tradition::Stemma]', + handles => { + stemmata => 'elements', + _add_stemma => 'push', + stemma => 'get', + stemma_count => 'count', + clear_stemmata => 'clear', + }, + default => sub { [] }, + ); + + +=head2 add_stemma( $dotfile ) + +Initializes a Text::Tradition::Stemma object from the given dotfile, +and associates it with the tradition. + +=begin testing + +use Text::Tradition; + +my $t = Text::Tradition->new( + 'name' => 'simple test', + 'input' => 'Tabular', + 'file' => 't/data/simple.txt', + ); +$t->enable_stemmata; +is( $t->stemma_count, 0, "No stemmas added yet" ); +my $s; +ok( $s = $t->add_stemma( dotfile => 't/data/simple.dot' ), "Added a simple stemma" ); +is( ref( $s ), 'Text::Tradition::Stemma', "Got a stemma object returned" ); +is( $t->stemma_count, 1, "Tradition claims to have a stemma" ); +is( $t->stemma(0), $s, "Tradition hands back the right stemma" ); + +=end testing + +=cut + +sub add_stemma { + my $self = shift; + my %opts = @_; + my $stemma_fh; + if( $opts{'dotfile'} ) { + open $stemma_fh, '<', $opts{'dotfile'} + or warn "Could not open file " . $opts{'dotfile'}; + } elsif( $opts{'dot'} ) { + my $str = $opts{'dot'}; + open $stemma_fh, '<', \$str; + } + # Assume utf-8 + binmode $stemma_fh, ':utf8'; + my $stemma = Text::Tradition::Stemma->new( + 'dot' => $stemma_fh ); + $self->_add_stemma( $stemma ) if $stemma; + return $stemma; +} + +1; + +=head1 LICENSE + +This package is free software and is provided "as is" without express +or implied warranty. You can redistribute it and/or modify it under +the same terms as Perl itself. + +=head1 AUTHOR + +Tara L Andrews Eaurum@cpan.orgE diff --git a/lib/Text/Tradition/Stemma.pm b/analysis/lib/Text/Tradition/Stemma.pm similarity index 99% rename from lib/Text/Tradition/Stemma.pm rename to analysis/lib/Text/Tradition/Stemma.pm index 765547e..b88226b 100644 --- a/lib/Text/Tradition/Stemma.pm +++ b/analysis/lib/Text/Tradition/Stemma.pm @@ -1,6 +1,5 @@ package Text::Tradition::Stemma; -use Bio::Phylo::IO; use Encode qw( decode_utf8 ); use File::Temp; use Graph; diff --git a/lib/Text/Tradition/StemmaUtil.pm b/analysis/lib/Text/Tradition/StemmaUtil.pm similarity index 99% rename from lib/Text/Tradition/StemmaUtil.pm rename to analysis/lib/Text/Tradition/StemmaUtil.pm index 5c3f848..1aba28b 100644 --- a/lib/Text/Tradition/StemmaUtil.pm +++ b/analysis/lib/Text/Tradition/StemmaUtil.pm @@ -10,7 +10,6 @@ use File::chdir; use File::Temp; use File::Which; use Graph; -use Graph::Reader::Dot; use IPC::Run qw/ run binary /; use Text::Tradition::Error; use Text::Tradition::Stemma; diff --git a/t/00dependencies.t b/analysis/t/00dependencies.t similarity index 100% copy from t/00dependencies.t copy to analysis/t/00dependencies.t diff --git a/t/analysis.t b/analysis/t/analysis.t similarity index 99% rename from t/analysis.t rename to analysis/t/analysis.t index bc5661f..08ac38f 100755 --- a/t/analysis.t +++ b/analysis/t/analysis.t @@ -15,6 +15,7 @@ eval { no warnings; binmode $DB::OUT, ':utf8'; $DB::deep = 1000 }; my $tradition = Text::Tradition->new( 'input' => 'Self', 'file' => 't/data/besoin.xml' ); +$tradition->enable_stemmata; $tradition->add_stemma( 'dotfile' => 't/data/besoin.dot' ); # Run the analysis of the tradition diff --git a/t/data/Collatex-16.xml b/analysis/t/data/Collatex-16.xml similarity index 100% copy from t/data/Collatex-16.xml copy to analysis/t/data/Collatex-16.xml diff --git a/t/data/analysis.db b/analysis/t/data/analysis.db similarity index 100% rename from t/data/analysis.db rename to analysis/t/data/analysis.db diff --git a/t/data/besoin.dot b/analysis/t/data/besoin.dot similarity index 100% rename from t/data/besoin.dot rename to analysis/t/data/besoin.dot diff --git a/t/data/besoin.xml b/analysis/t/data/besoin.xml similarity index 100% copy from t/data/besoin.xml copy to analysis/t/data/besoin.xml diff --git a/t/data/besoin_bad.dot b/analysis/t/data/besoin_bad.dot similarity index 100% rename from t/data/besoin_bad.dot rename to analysis/t/data/besoin_bad.dot diff --git a/t/data/florilegium.dot b/analysis/t/data/florilegium.dot similarity index 100% copy from t/data/florilegium.dot copy to analysis/t/data/florilegium.dot diff --git a/t/data/florilegium_tei_ps.xml b/analysis/t/data/florilegium_tei_ps.xml similarity index 100% copy from t/data/florilegium_tei_ps.xml copy to analysis/t/data/florilegium_tei_ps.xml diff --git a/t/data/simple.dot b/analysis/t/data/simple.dot similarity index 100% copy from t/data/simple.dot copy to analysis/t/data/simple.dot diff --git a/t/data/simple.txt b/analysis/t/data/simple.txt similarity index 100% copy from t/data/simple.txt copy to analysis/t/data/simple.txt diff --git a/t/inline2test.conf b/analysis/t/inline2test.conf similarity index 100% copy from t/inline2test.conf copy to analysis/t/inline2test.conf diff --git a/t/stemma.t b/analysis/t/stemma.t similarity index 82% rename from t/stemma.t rename to analysis/t/stemma.t index 84193a9..094c30b 100644 --- a/t/stemma.t +++ b/analysis/t/stemma.t @@ -6,8 +6,7 @@ use Test::More; use lib 'lib'; use Text::Tradition; use Text::Tradition::StemmaUtil qw/ character_input phylip_pars parse_newick /; -use XML::LibXML; -use XML::LibXML::XPathContext; +use TryCatch; my $datafile = 't/data/Collatex-16.xml'; #TODO need other test data @@ -23,6 +22,7 @@ $c->add_relationship( 'n9', 'n10', { 'type' => 'spelling' } ); $c->add_relationship( 'n12', 'n13', { 'type' => 'spelling' } ); $c->calculate_ranks(); +$tradition->enable_stemmata; my $stemma = $tradition->add_stemma( dotfile => 't/data/simple.dot' ); # Test for object creation @@ -51,16 +51,16 @@ foreach my $ml ( @mlines ) { # Test that pars runs SKIP: { - skip "pars not in path", 3 unless File::Which::which('pars'); - my $newick = phylip_pars( $mstr ); - ok( $newick, "pars ran successfully" ); + skip "pars not in path", 3 unless File::Which::which('pars'); + my $newick = phylip_pars( $mstr ); + ok( $newick, "pars ran successfully" ); my $trees = parse_newick( $newick ); - # Test that we get a tree - is( scalar @$trees, 1, "Got a single tree" ); - # Test that the tree has all our witnesses - my $tree = $trees->[0]; - is( scalar $tree->witnesses, 3, "All witnesses in the tree" ); + # Test that we get a tree + is( scalar @$trees, 1, "Got a single tree" ); + # Test that the tree has all our witnesses + my $tree = $trees->[0]; + is( scalar $tree->witnesses, 3, "All witnesses in the tree" ); } # Test our dot output @@ -71,5 +71,4 @@ ok( $display !~ /hypothetical/, "Graph is display rather than edit" ); my $editable = $stemma->editable(); ok( $editable =~ /digraph/, "Got a dot edit graph" ); ok( $editable =~ /hypothetical/, "Graph contains an edit class" ); - done_testing(); diff --git a/t/text_tradition_analysis.t b/analysis/t/text_tradition_analysis.t similarity index 98% rename from t/text_tradition_analysis.t rename to analysis/t/text_tradition_analysis.t index f568b36..1ebf655 100644 --- a/t/text_tradition_analysis.t +++ b/analysis/t/text_tradition_analysis.t @@ -15,6 +15,7 @@ my $datafile = 't/data/florilegium_tei_ps.xml'; my $tradition = Text::Tradition->new( 'input' => 'TEI', 'name' => 'test0', 'file' => $datafile ); +$tradition->enable_stemmata; my $s = $tradition->add_stemma( 'dotfile' => 't/data/florilegium.dot' ); is( ref( $s ), 'Text::Tradition::Stemma', "Added stemma to tradition" ); diff --git a/t/text_tradition_analysis_result.t b/analysis/t/text_tradition_analysis_result.t similarity index 99% rename from t/text_tradition_analysis_result.t rename to analysis/t/text_tradition_analysis_result.t index e3462dc..2997818 100644 --- a/t/text_tradition_analysis_result.t +++ b/analysis/t/text_tradition_analysis_result.t @@ -20,6 +20,7 @@ my $datafile = 't/data/florilegium_tei_ps.xml'; my $tradition = Text::Tradition->new( 'input' => 'TEI', 'name' => 'flortest', 'file' => $datafile ); +$tradition->enable_stemmata; my $s = $tradition->add_stemma( 'dotfile' => 't/data/florilegium.dot' ); my $sets = [ [ qw/ D Q / ], [ qw/ F H / ], [ qw/ A B C P S T / ] ]; diff --git a/analysis/t/text_tradition_hasstemma.t b/analysis/t/text_tradition_hasstemma.t new file mode 100644 index 0000000..ecf253e --- /dev/null +++ b/analysis/t/text_tradition_hasstemma.t @@ -0,0 +1,30 @@ +#!/usr/bin/perl -w + +use strict; +use Test::More 'no_plan'; +$| = 1; + + + +# =begin testing +{ +use Text::Tradition; + +my $t = Text::Tradition->new( + 'name' => 'simple test', + 'input' => 'Tabular', + 'file' => 't/data/simple.txt', + ); +$t->enable_stemmata; +is( $t->stemma_count, 0, "No stemmas added yet" ); +my $s; +ok( $s = $t->add_stemma( dotfile => 't/data/simple.dot' ), "Added a simple stemma" ); +is( ref( $s ), 'Text::Tradition::Stemma', "Got a stemma object returned" ); +is( $t->stemma_count, 1, "Tradition claims to have a stemma" ); +is( $t->stemma(0), $s, "Tradition hands back the right stemma" ); +} + + + + +1; diff --git a/t/text_tradition_stemma.t b/analysis/t/text_tradition_stemma.t similarity index 100% rename from t/text_tradition_stemma.t rename to analysis/t/text_tradition_stemma.t diff --git a/CHANGES b/base/CHANGES similarity index 100% rename from CHANGES rename to base/CHANGES diff --git a/base/MANIFEST.SKIP b/base/MANIFEST.SKIP new file mode 100644 index 0000000..3b31671 --- /dev/null +++ b/base/MANIFEST.SKIP @@ -0,0 +1,5 @@ +lib/Text/Tradition/Parser/BaseText.pm +lib/Text/Tradition/Parser/CollateText.pm +lib/Text/Tradition/Parser/KUL.pm +.git/ +.gitignore diff --git a/Makefile.PL b/base/Makefile.PL similarity index 96% rename from Makefile.PL rename to base/Makefile.PL index 3aa72f4..c85aaa5 100644 --- a/Makefile.PL +++ b/base/Makefile.PL @@ -23,7 +23,9 @@ requires( 'KiokuX::Model' ); requires( 'KiokuX::User::Util' ); requires( 'Module::Load' ); requires( 'Moose' ); +requires( 'Moose::Util' ); requires( 'Moose::Util::TypeConstraints' ); +requires( 'Safe::Isa' ); requires( 'Spreadsheet::ParseExcel' ); requires( 'Spreadsheet::XLSX' ); requires( 'StackTrace::Auto' ); diff --git a/TODO b/base/TODO similarity index 100% rename from TODO rename to base/TODO diff --git a/doc/graph_format.txt b/base/doc/graph_format.txt similarity index 100% rename from doc/graph_format.txt rename to base/doc/graph_format.txt diff --git a/idp_server/graphcalc.cgi b/base/idp_server/graphcalc.cgi similarity index 100% rename from idp_server/graphcalc.cgi rename to base/idp_server/graphcalc.cgi diff --git a/idp_server/graphcalc_worker.pl b/base/idp_server/graphcalc_worker.pl similarity index 100% rename from idp_server/graphcalc_worker.pl rename to base/idp_server/graphcalc_worker.pl diff --git a/lib/Text/Tradition.pm b/base/lib/Text/Tradition.pm similarity index 87% rename from lib/Text/Tradition.pm rename to base/lib/Text/Tradition.pm index 41e14cc..51258dc 100644 --- a/lib/Text/Tradition.pm +++ b/base/lib/Text/Tradition.pm @@ -3,10 +3,12 @@ package Text::Tradition; use JSON qw / from_json /; use Module::Load; use Moose; +use Moose::Util qw/ does_role apply_all_roles /; use Text::Tradition::Collation; -use Text::Tradition::Stemma; +use Text::Tradition::Error; use Text::Tradition::Witness; use Text::Tradition::User; +use TryCatch; use vars qw( $VERSION ); $VERSION = "0.5"; @@ -42,19 +44,6 @@ has 'language' => ( predicate => 'has_language', ); -has 'stemmata' => ( - traits => ['Array'], - isa => 'ArrayRef[Text::Tradition::Stemma]', - handles => { - stemmata => 'elements', - _add_stemma => 'push', - stemma => 'get', - stemma_count => 'count', - clear_stemmata => 'clear', - }, - default => sub { [] }, - ); - has '_initialized' => ( is => 'ro', isa => 'Bool', @@ -335,49 +324,25 @@ sub add_json_witnesses { } } -=head2 add_stemma( $dotfile ) - -Initializes a Text::Tradition::Stemma object from the given dotfile, -and associates it with the tradition. - -=begin testing - -use Text::Tradition; +=head1 PLUGIN HOOKS -my $t = Text::Tradition->new( - 'name' => 'simple test', - 'input' => 'Tabular', - 'file' => 't/data/simple.txt', - ); - -is( $t->stemma_count, 0, "No stemmas added yet" ); -my $s; -ok( $s = $t->add_stemma( dotfile => 't/data/simple.dot' ), "Added a simple stemma" ); -is( ref( $s ), 'Text::Tradition::Stemma', "Got a stemma object returned" ); -is( $t->stemma_count, 1, "Tradition claims to have a stemma" ); -is( $t->stemma(0), $s, "Tradition hands back the right stemma" ); +=head2 enable_stemmata(); -=end testing +If the tradition in question does not have the HasStemma role, make it so. Throws +an error if the role (ergo, if the Analysis package) is not installed. =cut -sub add_stemma { +sub enable_stemmata { my $self = shift; - my %opts = @_; - my $stemma_fh; - if( $opts{'dotfile'} ) { - open $stemma_fh, '<', $opts{'dotfile'} - or warn "Could not open file " . $opts{'dotfile'}; - } elsif( $opts{'dot'} ) { - my $str = $opts{'dot'}; - open $stemma_fh, '<', \$str; + my $rolename = 'Text::Tradition::HasStemma'; + return 1 if does_role( $self, $rolename ); + try { + apply_all_roles( $self, $rolename ); + } catch { + throw( "Cannot apply role to enable stemmata; is the Analysis extension installed?" ); } - # Assume utf-8 - binmode $stemma_fh, ':utf8'; - my $stemma = Text::Tradition::Stemma->new( - 'dot' => $stemma_fh ); - $self->_add_stemma( $stemma ) if $stemma; - return $stemma; + return 1; } sub lemmatize { @@ -391,6 +356,13 @@ sub lemmatize { $mod->can( 'lemmatize' )->( $self ); } +sub throw { + Text::Tradition::Error->throw( + 'ident' => 'Tradition error', + 'message' => $_[0], + ); +} + no Moose; __PACKAGE__->meta->make_immutable; diff --git a/lib/Text/Tradition/Collation.pm b/base/lib/Text/Tradition/Collation.pm similarity index 98% rename from lib/Text/Tradition/Collation.pm rename to base/lib/Text/Tradition/Collation.pm index 022c2bc..d652850 100644 --- a/lib/Text/Tradition/Collation.pm +++ b/base/lib/Text/Tradition/Collation.pm @@ -897,6 +897,7 @@ readings. This is the native transfer format for a tradition. =begin testing use Text::Tradition; +use TryCatch; my $READINGS = 311; my $PATHS = 361; @@ -930,11 +931,20 @@ is( scalar $st->collation->paths, $PATHS, "Reparsed collation has all paths" ); is( scalar $st->collation->relationships, 3, "Reparsed collation has new relationships" ); # Now add a stemma, write to GraphML, and look at the output. -my $stemma = $tradition->add_stemma( 'dotfile' => 't/data/florilegium.dot' ); -is( ref( $stemma ), 'Text::Tradition::Stemma', "Parsed dotfile into stemma" ); -is( $tradition->stemmata, 1, "Tradition now has the stemma" ); -$graphml = $c->as_graphml; -like( $graphml, qr/digraph/, "Digraph declaration exists in GraphML" ); +my $SKIP_STEMMA; +try { + $tradition->enable_stemmata; +} catch { + $SKIP_STEMMA = 1; +} +SKIP: { + skip "Analysis module not present", 3 if $SKIP_STEMMA; + my $stemma = $tradition->add_stemma( 'dotfile' => 't/data/florilegium.dot' ); + is( ref( $stemma ), 'Text::Tradition::Stemma', "Parsed dotfile into stemma" ); + is( $tradition->stemmata, 1, "Tradition now has the stemma" ); + $graphml = $c->as_graphml; + like( $graphml, qr/digraph/, "Digraph declaration exists in GraphML" ); +} # Now add a user, write to GraphML, and look at the output. unlike( $graphml, qr/testuser/, "Test user name does not exist in GraphML yet" ); @@ -950,6 +960,7 @@ like( $graphml, qr/testuser/, "Test user name now exists in GraphML" ); =cut +## TODO MOVE this to Tradition.pm sub as_graphml { my( $self, $options ) = @_; $self->calculate_ranks unless $self->_graphcalc_done; @@ -1013,12 +1024,15 @@ sub as_graphml { } # Extra custom keys for complex objects that should be saved in some form. # The subroutine should return a string, or undef/empty. - $graph_attributes{'stemmata'} = sub { - my @stemstrs; - map { push( @stemstrs, $_->editable( {linesep => ''} ) ) } - $self->tradition->stemmata; - join( "\n", @stemstrs ); - }; + if( $tmeta->has_method('stemmata') ) { + $graph_attributes{'stemmata'} = sub { + my @stemstrs; + map { push( @stemstrs, $_->editable( {linesep => ''} ) ) } + $self->tradition->stemmata; + join( "\n", @stemstrs ); + }; + } + $graph_attributes{'user'} = sub { $self->tradition->user ? $self->tradition->user->id : undef }; diff --git a/lib/Text/Tradition/Collation/Data.pm b/base/lib/Text/Tradition/Collation/Data.pm similarity index 100% rename from lib/Text/Tradition/Collation/Data.pm rename to base/lib/Text/Tradition/Collation/Data.pm diff --git a/lib/Text/Tradition/Collation/Reading.pm b/base/lib/Text/Tradition/Collation/Reading.pm similarity index 100% rename from lib/Text/Tradition/Collation/Reading.pm rename to base/lib/Text/Tradition/Collation/Reading.pm diff --git a/lib/Text/Tradition/Collation/Reading/Lexeme.pm b/base/lib/Text/Tradition/Collation/Reading/Lexeme.pm similarity index 100% rename from lib/Text/Tradition/Collation/Reading/Lexeme.pm rename to base/lib/Text/Tradition/Collation/Reading/Lexeme.pm diff --git a/lib/Text/Tradition/Collation/Reading/WordForm.pm b/base/lib/Text/Tradition/Collation/Reading/WordForm.pm similarity index 100% rename from lib/Text/Tradition/Collation/Reading/WordForm.pm rename to base/lib/Text/Tradition/Collation/Reading/WordForm.pm diff --git a/lib/Text/Tradition/Collation/Relationship.pm b/base/lib/Text/Tradition/Collation/Relationship.pm similarity index 100% rename from lib/Text/Tradition/Collation/Relationship.pm rename to base/lib/Text/Tradition/Collation/Relationship.pm diff --git a/lib/Text/Tradition/Collation/RelationshipStore.pm b/base/lib/Text/Tradition/Collation/RelationshipStore.pm similarity index 100% rename from lib/Text/Tradition/Collation/RelationshipStore.pm rename to base/lib/Text/Tradition/Collation/RelationshipStore.pm diff --git a/lib/Text/Tradition/Directory.pm b/base/lib/Text/Tradition/Directory.pm similarity index 90% rename from lib/Text/Tradition/Directory.pm rename to base/lib/Text/Tradition/Directory.pm index 0734168..542ad4d 100644 --- a/lib/Text/Tradition/Directory.pm +++ b/base/lib/Text/Tradition/Directory.pm @@ -8,6 +8,7 @@ use Encode qw/ decode_utf8 /; use KiokuDB::GC::Naive; use KiokuDB::TypeMap; use KiokuDB::TypeMap::Entry::Naive; +use Safe::Isa; use Text::Tradition::Error; ## users @@ -31,6 +32,7 @@ Text::Tradition::Directory - a KiokuDB interface for storing and retrieving trad ); my $tradition = Text::Tradition->new( @args ); + $tradition->enable_stemmata; my $stemma = $tradition->add_stemma( dotfile => $dotfile ); $d->save_tradition( $tradition ); @@ -95,6 +97,7 @@ WARNING!! Garbage collection does not yet work. Use this sparingly. use TryCatch; use File::Temp; +use Safe::Isa; use Text::Tradition; use_ok 'Text::Tradition::Directory'; @@ -108,26 +111,31 @@ my $t = Text::Tradition->new( 'input' => 'Tabular', 'file' => 't/data/simple.txt', ); +my $stemma_enabled; +eval { $stemma_enabled = $t->enable_stemmata; }; { my $d = Text::Tradition::Directory->new( 'dsn' => $dsn, 'extra_args' => { 'create' => 1 } ); - is( ref $d, 'Text::Tradition::Directory', "Got directory object" ); + ok( $d->$_isa('Text::Tradition::Directory'), "Got directory object" ); my $scope = $d->new_scope; $uuid = $d->save( $t ); ok( $uuid, "Saved test tradition" ); - my $s = $t->add_stemma( dotfile => 't/data/simple.dot' ); - ok( $d->save( $t ), "Updated tradition with stemma" ); - is( $d->tradition( $uuid ), $t, "Correct tradition returned for id" ); - is( $d->tradition( $uuid )->stemma(0), $s, "...and it has the correct stemma" ); - try { - $d->save( $s ); - } catch( Text::Tradition::Error $e ) { - is( $e->ident, 'database error', "Got exception trying to save stemma directly" ); - like( $e->message, qr/Cannot directly save non-Tradition object/, - "Exception has correct message" ); + SKIP: { + skip "Analysis package not installed", 5 unless $stemma_enabled; + my $s = $t->add_stemma( dotfile => 't/data/simple.dot' ); + ok( $d->save( $t ), "Updated tradition with stemma" ); + is( $d->tradition( $uuid ), $t, "Correct tradition returned for id" ); + is( $d->tradition( $uuid )->stemma(0), $s, "...and it has the correct stemma" ); + try { + $d->save( $s ); + } catch( Text::Tradition::Error $e ) { + is( $e->ident, 'database error', "Got exception trying to save stemma directly" ); + like( $e->message, qr/Cannot directly save non-Tradition object/, + "Exception has correct message" ); + } } } my $nt = Text::Tradition->new( @@ -135,7 +143,7 @@ my $nt = Text::Tradition->new( 'input' => 'CollateX', 'file' => 't/data/Collatex-16.xml', ); -is( ref( $nt ), 'Text::Tradition', "Made new tradition" ); +ok( $nt->$_isa('Text::Tradition'), "Made new tradition" ); { my $f = Text::Tradition::Directory->new( 'dsn' => $dsn ); @@ -149,24 +157,28 @@ is( ref( $nt ), 'Text::Tradition', "Made new tradition" ); my( $tlobj ) = grep { $_->{'id'} eq $uuid } @tlist; is( $tlobj->{'name'}, $tf->name, "Directory index has correct tradition name" ); is( $tf->name, $t->name, "Retrieved the tradition from a new directory" ); - my $sid = $f->object_to_id( $tf->stemma(0) ); - try { - $f->tradition( $sid ); - } catch( Text::Tradition::Error $e ) { - is( $e->ident, 'database error', "Got exception trying to fetch stemma directly" ); - like( $e->message, qr/not a Text::Tradition/, "Exception has correct message" ); - } - try { - $f->delete( $sid ); - } catch( Text::Tradition::Error $e ) { - is( $e->ident, 'database error', "Got exception trying to delete stemma directly" ); - like( $e->message, qr/Cannot directly delete non-Tradition object/, - "Exception has correct message" ); + my $sid; + SKIP: { + skip "Analysis package not installed", 4 unless $stemma_enabled; + $sid = $f->object_to_id( $tf->stemma(0) ); + try { + $f->tradition( $sid ); + } catch( Text::Tradition::Error $e ) { + is( $e->ident, 'database error', "Got exception trying to fetch stemma directly" ); + like( $e->message, qr/not a Text::Tradition/, "Exception has correct message" ); + } + try { + $f->delete( $sid ); + } catch( Text::Tradition::Error $e ) { + is( $e->ident, 'database error', "Got exception trying to delete stemma directly" ); + like( $e->message, qr/Cannot directly delete non-Tradition object/, + "Exception has correct message" ); + } } $f->delete( $uuid ); ok( !$f->exists( $uuid ), "Object is deleted from DB" ); - ok( !$f->exists( $sid ), "Object stemma also deleted from DB" ); + ok( !$f->exists( $sid ), "Object stemma also deleted from DB" ) if $stemma_enabled; is( scalar $f->traditionlist, 1, "Object is deleted from index" ); } @@ -256,12 +268,12 @@ before [ qw/ delete / ] => sub { my $self = shift; my @nontrad; foreach my $obj ( @_ ) { - if( ref( $obj ) && ref( $obj ) ne 'Text::Tradition' - && ref ($obj) ne 'Text::Tradition::User' ) { + if( ref( $obj ) && !$obj->$_isa( 'Text::Tradition' ) + && !$obj->$_isa('Text::Tradition::User') ) { # Is it an id => Tradition hash? if( ref( $obj ) eq 'HASH' && keys( %$obj ) == 1 ) { my( $k ) = keys %$obj; - next if ref( $obj->{$k} ) eq 'Text::Tradition'; + next if $obj->{$k}->$_isa('Text::Tradition'); } push( @nontrad, $obj ); } @@ -297,7 +309,7 @@ sub tradition { } } } - if( $obj && ref( $obj ) ne 'Text::Tradition' ) { + if( $obj && !$obj->$_isa('Text::Tradition') ) { throw( "Retrieved object is a " . ref( $obj ) . ", not a Text::Tradition" ); } return $obj; diff --git a/lib/Text/Tradition/Error.pm b/base/lib/Text/Tradition/Error.pm similarity index 100% rename from lib/Text/Tradition/Error.pm rename to base/lib/Text/Tradition/Error.pm diff --git a/lib/Text/Tradition/Language/Armenian.pm b/base/lib/Text/Tradition/Language/Armenian.pm similarity index 100% rename from lib/Text/Tradition/Language/Armenian.pm rename to base/lib/Text/Tradition/Language/Armenian.pm diff --git a/lib/Text/Tradition/Language/Base.pm b/base/lib/Text/Tradition/Language/Base.pm similarity index 100% rename from lib/Text/Tradition/Language/Base.pm rename to base/lib/Text/Tradition/Language/Base.pm diff --git a/lib/Text/Tradition/Language/English.pm b/base/lib/Text/Tradition/Language/English.pm similarity index 100% rename from lib/Text/Tradition/Language/English.pm rename to base/lib/Text/Tradition/Language/English.pm diff --git a/lib/Text/Tradition/Language/French.pm b/base/lib/Text/Tradition/Language/French.pm similarity index 100% rename from lib/Text/Tradition/Language/French.pm rename to base/lib/Text/Tradition/Language/French.pm diff --git a/lib/Text/Tradition/Language/Greek.pm b/base/lib/Text/Tradition/Language/Greek.pm similarity index 100% rename from lib/Text/Tradition/Language/Greek.pm rename to base/lib/Text/Tradition/Language/Greek.pm diff --git a/lib/Text/Tradition/Language/Latin.pm b/base/lib/Text/Tradition/Language/Latin.pm similarity index 100% rename from lib/Text/Tradition/Language/Latin.pm rename to base/lib/Text/Tradition/Language/Latin.pm diff --git a/lib/Text/Tradition/Language/Perseus.pm b/base/lib/Text/Tradition/Language/Perseus.pm similarity index 100% rename from lib/Text/Tradition/Language/Perseus.pm rename to base/lib/Text/Tradition/Language/Perseus.pm diff --git a/lib/Text/Tradition/Parser/BaseText.pm b/base/lib/Text/Tradition/Parser/BaseText.pm similarity index 100% rename from lib/Text/Tradition/Parser/BaseText.pm rename to base/lib/Text/Tradition/Parser/BaseText.pm diff --git a/lib/Text/Tradition/Parser/CTE.pm b/base/lib/Text/Tradition/Parser/CTE.pm similarity index 100% rename from lib/Text/Tradition/Parser/CTE.pm rename to base/lib/Text/Tradition/Parser/CTE.pm diff --git a/lib/Text/Tradition/Parser/CollateText.pm b/base/lib/Text/Tradition/Parser/CollateText.pm similarity index 100% rename from lib/Text/Tradition/Parser/CollateText.pm rename to base/lib/Text/Tradition/Parser/CollateText.pm diff --git a/lib/Text/Tradition/Parser/CollateX.pm b/base/lib/Text/Tradition/Parser/CollateX.pm similarity index 100% rename from lib/Text/Tradition/Parser/CollateX.pm rename to base/lib/Text/Tradition/Parser/CollateX.pm diff --git a/lib/Text/Tradition/Parser/GraphML.pm b/base/lib/Text/Tradition/Parser/GraphML.pm similarity index 100% rename from lib/Text/Tradition/Parser/GraphML.pm rename to base/lib/Text/Tradition/Parser/GraphML.pm diff --git a/lib/Text/Tradition/Parser/JSON.pm b/base/lib/Text/Tradition/Parser/JSON.pm similarity index 100% rename from lib/Text/Tradition/Parser/JSON.pm rename to base/lib/Text/Tradition/Parser/JSON.pm diff --git a/lib/Text/Tradition/Parser/KUL.pm b/base/lib/Text/Tradition/Parser/KUL.pm similarity index 100% rename from lib/Text/Tradition/Parser/KUL.pm rename to base/lib/Text/Tradition/Parser/KUL.pm diff --git a/lib/Text/Tradition/Parser/Self.pm b/base/lib/Text/Tradition/Parser/Self.pm similarity index 89% rename from lib/Text/Tradition/Parser/Self.pm rename to base/lib/Text/Tradition/Parser/Self.pm index 981a855..255f804 100644 --- a/lib/Text/Tradition/Parser/Self.pm +++ b/base/lib/Text/Tradition/Parser/Self.pm @@ -97,8 +97,10 @@ source of the XML to be parsed. =begin testing use File::Temp; +use Safe::Isa; use Test::Warn; use Text::Tradition; +use TryCatch; binmode STDOUT, ":utf8"; binmode STDERR, ":utf8"; eval { no warnings; binmode $DB::OUT, ":utf8"; }; @@ -110,7 +112,7 @@ my $t = Text::Tradition->new( 'file' => $tradition, ); -is( ref( $t ), 'Text::Tradition', "Parsed GraphML version 2" ); +ok( $t->$_isa('Text::Tradition'), "Parsed GraphML version 2" ); if( $t ) { is( scalar $t->collation->readings, 319, "Collation has all readings" ); is( scalar $t->collation->paths, 376, "Collation has all paths" ); @@ -120,7 +122,15 @@ if( $t ) { # TODO add a relationship, add a stemma, write graphml, reparse it, check that # the new data is there $t->language('Greek'); -$t->add_stemma( 'dotfile' => 't/data/florilegium.dot' ); +my $stemma_enabled; +try { + $stemma_enabled = $t->enable_stemmata; +} catch { + ok( 1, "Skipping stemma tests without Analysis module" ); +} +if( $stemma_enabled ) { + $t->add_stemma( 'dotfile' => 't/data/florilegium.dot' ); +} $t->collation->add_relationship( 'w12', 'w13', { 'type' => 'grammatical', 'scope' => 'global', 'annotation' => 'This is some note' } ); @@ -128,7 +138,7 @@ ok( $t->collation->get_relationship( 'w12', 'w13' ), "Relationship set" ); my $graphml_str = $t->collation->as_graphml; my $newt = Text::Tradition->new( 'input' => 'Self', 'string' => $graphml_str ); -is( ref( $newt ), 'Text::Tradition', "Parsed current GraphML version" ); +ok( $newt->$_isa('Text::Tradition'), "Parsed current GraphML version" ); if( $newt ) { is( scalar $newt->collation->readings, 319, "Collation has all readings" ); is( scalar $newt->collation->paths, 376, "Collation has all paths" ); @@ -138,8 +148,10 @@ if( $newt ) { my $rel = $newt->collation->get_relationship( 'w12', 'w13' ); ok( $rel, "Found set relationship" ); is( $rel->annotation, 'This is some note', "Relationship has its properties" ); - is( scalar $newt->stemmata, 1, "Tradition has its stemma" ); - is( $newt->stemma(0)->witnesses, $t->stemma(0)->witnesses, "Stemma has correct length witness list" ); + if( $stemma_enabled ) { + is( scalar $newt->stemmata, 1, "Tradition has its stemma" ); + is( $newt->stemma(0)->witnesses, $t->stemma(0)->witnesses, "Stemma has correct length witness list" ); + } } # Test user save / restore @@ -151,7 +163,7 @@ my $userstore = Text::Tradition::Directory->new( { dsn => $dsn, extra_args => { create => 1 } } ); my $scope = $userstore->new_scope(); my $testuser = $userstore->create_user( { url => 'http://example.com' } ); -is( ref( $testuser ), 'Text::Tradition::User', "Created test user via userstore" ); +ok( $testuser->$_isa('Text::Tradition::User'), "Created test user via userstore" ); $testuser->add_tradition( $newt ); is( $newt->user->id, $testuser->id, "Assigned tradition to test user" ); $graphml_str = $newt->collation->as_graphml; @@ -164,6 +176,14 @@ $usert = Text::Tradition->new( 'input' => 'Self', 'string' => $graphml_str, 'userstore' => $userstore ); is( $usert->user->id, $testuser->id, "Parsed tradition with userstore points to correct user" ); +# Test warning if we can +unless( $stemma_enabled ) { + my $nst; + warnings_exist { + $nst = Text::Tradition->new( 'input' => 'Self', 'file' => 't/data/lexformat.xml' ); + } [qr/DROPPING stemmata/], + "Got expected stemma drop warning on parse"; +} =end testing @@ -190,9 +210,18 @@ sub parse { if( $gkey eq 'version' ) { $use_version = $val; } elsif( $gkey eq 'stemmata' ) { + # Make sure we can handle stemmata + my $stemma_enabled; + try { + $stemma_enabled = $tradition->enable_stemmata; + } catch { + warn "Analysis module not installed; DROPPING stemmata"; + } # Parse the stemmata into objects - foreach my $dotstr ( split( /\n/, $val ) ) { - $tradition->add_stemma( 'dot' => $dotstr ); + if( $stemma_enabled ) { + foreach my $dotstr ( split( /\n/, $val ) ) { + $tradition->add_stemma( 'dot' => $dotstr ); + } } } elsif( $gkey eq 'user' ) { # Assign the tradition to the user if we can diff --git a/lib/Text/Tradition/Parser/TEI.pm b/base/lib/Text/Tradition/Parser/TEI.pm similarity index 100% rename from lib/Text/Tradition/Parser/TEI.pm rename to base/lib/Text/Tradition/Parser/TEI.pm diff --git a/lib/Text/Tradition/Parser/Tabular.pm b/base/lib/Text/Tradition/Parser/Tabular.pm similarity index 100% rename from lib/Text/Tradition/Parser/Tabular.pm rename to base/lib/Text/Tradition/Parser/Tabular.pm diff --git a/lib/Text/Tradition/Parser/Util.pm b/base/lib/Text/Tradition/Parser/Util.pm similarity index 100% rename from lib/Text/Tradition/Parser/Util.pm rename to base/lib/Text/Tradition/Parser/Util.pm diff --git a/lib/Text/Tradition/Store.pm b/base/lib/Text/Tradition/Store.pm similarity index 100% rename from lib/Text/Tradition/Store.pm rename to base/lib/Text/Tradition/Store.pm diff --git a/lib/Text/Tradition/TypeMap/Entry.pm b/base/lib/Text/Tradition/TypeMap/Entry.pm similarity index 100% rename from lib/Text/Tradition/TypeMap/Entry.pm rename to base/lib/Text/Tradition/TypeMap/Entry.pm diff --git a/lib/Text/Tradition/User.pm b/base/lib/Text/Tradition/User.pm similarity index 100% rename from lib/Text/Tradition/User.pm rename to base/lib/Text/Tradition/User.pm diff --git a/lib/Text/Tradition/UserStore.pm b/base/lib/Text/Tradition/UserStore.pm similarity index 100% rename from lib/Text/Tradition/UserStore.pm rename to base/lib/Text/Tradition/UserStore.pm diff --git a/lib/Text/Tradition/Witness.pm b/base/lib/Text/Tradition/Witness.pm similarity index 100% rename from lib/Text/Tradition/Witness.pm rename to base/lib/Text/Tradition/Witness.pm diff --git a/script/admin_users.pl b/base/script/admin_users.pl similarity index 100% rename from script/admin_users.pl rename to base/script/admin_users.pl diff --git a/script/analyze.pl b/base/script/analyze.pl similarity index 100% rename from script/analyze.pl rename to base/script/analyze.pl diff --git a/script/dblookup.pl b/base/script/dblookup.pl similarity index 100% rename from script/dblookup.pl rename to base/script/dblookup.pl diff --git a/script/group_vars.pl b/base/script/group_vars.pl similarity index 100% rename from script/group_vars.pl rename to base/script/group_vars.pl diff --git a/script/join_readings.pl b/base/script/join_readings.pl similarity index 100% rename from script/join_readings.pl rename to base/script/join_readings.pl diff --git a/script/majority_text.pl b/base/script/majority_text.pl similarity index 100% rename from script/majority_text.pl rename to base/script/majority_text.pl diff --git a/script/make_tradition.pl b/base/script/make_tradition.pl similarity index 100% rename from script/make_tradition.pl rename to base/script/make_tradition.pl diff --git a/script/maketestdb.sh b/base/script/maketestdb.sh similarity index 100% rename from script/maketestdb.sh rename to base/script/maketestdb.sh diff --git a/script/orth_case_links.pl b/base/script/orth_case_links.pl similarity index 100% rename from script/orth_case_links.pl rename to base/script/orth_case_links.pl diff --git a/script/poslink.pl b/base/script/poslink.pl similarity index 100% rename from script/poslink.pl rename to base/script/poslink.pl diff --git a/script/propagate_transitive.pl b/base/script/propagate_transitive.pl similarity index 100% rename from script/propagate_transitive.pl rename to base/script/propagate_transitive.pl diff --git a/script/statistics.pl b/base/script/statistics.pl similarity index 100% rename from script/statistics.pl rename to base/script/statistics.pl diff --git a/script/strip_punctuation.pl b/base/script/strip_punctuation.pl similarity index 100% rename from script/strip_punctuation.pl rename to base/script/strip_punctuation.pl diff --git a/t/00dependencies.t b/base/t/00dependencies.t similarity index 100% rename from t/00dependencies.t rename to base/t/00dependencies.t diff --git a/t/01app.t b/base/t/01app.t similarity index 100% rename from t/01app.t rename to base/t/01app.t diff --git a/t/02pod.t b/base/t/02pod.t similarity index 100% rename from t/02pod.t rename to base/t/02pod.t diff --git a/t/03podcoverage.t b/base/t/03podcoverage.t similarity index 100% rename from t/03podcoverage.t rename to base/t/03podcoverage.t diff --git a/t/bin/make-load-test.pl b/base/t/bin/make-load-test.pl similarity index 100% rename from t/bin/make-load-test.pl rename to base/t/bin/make-load-test.pl diff --git a/t/bin/update-load-test.pl b/base/t/bin/update-load-test.pl similarity index 100% rename from t/bin/update-load-test.pl rename to base/t/bin/update-load-test.pl diff --git a/t/data/Collatex-16.xml b/base/t/data/Collatex-16.xml similarity index 100% rename from t/data/Collatex-16.xml rename to base/t/data/Collatex-16.xml diff --git a/t/data/armexample.xls b/base/t/data/armexample.xls similarity index 100% rename from t/data/armexample.xls rename to base/t/data/armexample.xls diff --git a/t/data/armexample.xlsx b/base/t/data/armexample.xlsx similarity index 100% rename from t/data/armexample.xlsx rename to base/t/data/armexample.xlsx diff --git a/t/data/besoin.xml b/base/t/data/besoin.xml similarity index 100% rename from t/data/besoin.xml rename to base/t/data/besoin.xml diff --git a/t/data/cx16.json b/base/t/data/cx16.json similarity index 100% rename from t/data/cx16.json rename to base/t/data/cx16.json diff --git a/t/data/florilegium.csv b/base/t/data/florilegium.csv similarity index 100% rename from t/data/florilegium.csv rename to base/t/data/florilegium.csv diff --git a/t/data/florilegium.dot b/base/t/data/florilegium.dot similarity index 100% rename from t/data/florilegium.dot rename to base/t/data/florilegium.dot diff --git a/t/data/florilegium_graphml.xml b/base/t/data/florilegium_graphml.xml similarity index 100% rename from t/data/florilegium_graphml.xml rename to base/t/data/florilegium_graphml.xml diff --git a/t/data/florilegium_tei_cte.xml b/base/t/data/florilegium_tei_cte.xml similarity index 100% rename from t/data/florilegium_tei_cte.xml rename to base/t/data/florilegium_tei_cte.xml diff --git a/t/data/florilegium_tei_ps.xml b/base/t/data/florilegium_tei_ps.xml similarity index 100% rename from t/data/florilegium_tei_ps.xml rename to base/t/data/florilegium_tei_ps.xml diff --git a/t/data/john.xml b/base/t/data/john.xml similarity index 100% rename from t/data/john.xml rename to base/t/data/john.xml diff --git a/t/data/legendfrag.xml b/base/t/data/legendfrag.xml similarity index 100% rename from t/data/legendfrag.xml rename to base/t/data/legendfrag.xml diff --git a/t/data/lexformat.xml b/base/t/data/lexformat.xml similarity index 100% rename from t/data/lexformat.xml rename to base/t/data/lexformat.xml diff --git a/t/data/lf2.xml b/base/t/data/lf2.xml similarity index 100% rename from t/data/lf2.xml rename to base/t/data/lf2.xml diff --git a/t/data/load-save-benchmark.json b/base/t/data/load-save-benchmark.json similarity index 100% rename from t/data/load-save-benchmark.json rename to base/t/data/load-save-benchmark.json diff --git a/t/data/simple.dot b/base/t/data/simple.dot similarity index 100% rename from t/data/simple.dot rename to base/t/data/simple.dot diff --git a/t/data/simple.txt b/base/t/data/simple.txt similarity index 100% rename from t/data/simple.txt rename to base/t/data/simple.txt diff --git a/t/data/speed_test_load.sql b/base/t/data/speed_test_load.sql similarity index 100% rename from t/data/speed_test_load.sql rename to base/t/data/speed_test_load.sql diff --git a/t/data/witnesses/group.xml b/base/t/data/witnesses/group.xml similarity index 100% rename from t/data/witnesses/group.xml rename to base/t/data/witnesses/group.xml diff --git a/t/data/witnesses/teiwit.xml b/base/t/data/witnesses/teiwit.xml similarity index 100% rename from t/data/witnesses/teiwit.xml rename to base/t/data/witnesses/teiwit.xml diff --git a/t/data/witnesses/testwit.json b/base/t/data/witnesses/testwit.json similarity index 100% rename from t/data/witnesses/testwit.json rename to base/t/data/witnesses/testwit.json diff --git a/t/graph.t b/base/t/graph.t similarity index 100% rename from t/graph.t rename to base/t/graph.t diff --git a/t/inline2test.conf b/base/t/inline2test.conf similarity index 100% rename from t/inline2test.conf rename to base/t/inline2test.conf diff --git a/t/lexeme_serialize.t b/base/t/lexeme_serialize.t similarity index 85% rename from t/lexeme_serialize.t rename to base/t/lexeme_serialize.t index 7db1bae..401432b 100644 --- a/t/lexeme_serialize.t +++ b/base/t/lexeme_serialize.t @@ -1,6 +1,7 @@ use lib 'lib'; use strict; use warnings; +use Safe::Isa; use Test::More; use Text::Tradition; @@ -25,11 +26,11 @@ my $tf2 = Text::Tradition->new( string => $graphmlstr, language => 'French' ); -is( ref $tf2, 'Text::Tradition', "Re-parsed tradition with lemmatization" ); +ok( $tf2->$_isa('Text::Tradition'), "Re-parsed tradition with lemmatization" ); is( $tf->name, $tf2->name, "Traditions have same name" ); foreach my $r ( $tf->collation->readings ) { my $r2 = $tf2->collation->reading( $r->id ); - is( ref $r2, 'Text::Tradition::Collation::Reading', + ok( $r2->$_isa('Text::Tradition::Collation::Reading'), "Reading $r exists in new tradition" ); if( $r2 ) { is( scalar $r->lexemes, scalar $r2->lexemes, @@ -41,7 +42,7 @@ foreach my $r ( $tf->collation->readings ) { my $tf3 = Text::Tradition->new( 'input' => 'Self', 'file' => 't/data/lexformat.xml' ); -is( ref $tf3, 'Text::Tradition', +ok( $tf3->$_isa('Text::Tradition'), "Successfully parsed tradition with incomplete lexemes" ); done_testing(); diff --git a/t/load-save-speed.t b/base/t/load-save-speed.t similarity index 98% rename from t/load-save-speed.t rename to base/t/load-save-speed.t index ad4bf53..30837da 100644 --- a/t/load-save-speed.t +++ b/base/t/load-save-speed.t @@ -55,7 +55,7 @@ my $tradition = Text::Tradition->new( # 'input' => 'Tabular', # 'file' => 't/data/simple.txt', ); -$tradition->add_stemma(dotfile => "t/data/${test_name}.dot"); +#$tradition->add_stemma(dotfile => "t/data/${test_name}.dot"); #my $fh = File::Temp->new(); #my $file = $fh->filename; diff --git a/t/text_tradition.t b/base/t/text_tradition.t similarity index 74% rename from t/text_tradition.t rename to base/t/text_tradition.t index 2c7be1b..7e1718a 100644 --- a/t/text_tradition.t +++ b/base/t/text_tradition.t @@ -47,25 +47,5 @@ is( scalar $s->witnesses, 3, "object has three witnesses again" ); -# =begin testing -{ -use Text::Tradition; - -my $t = Text::Tradition->new( - 'name' => 'simple test', - 'input' => 'Tabular', - 'file' => 't/data/simple.txt', - ); - -is( $t->stemma_count, 0, "No stemmas added yet" ); -my $s; -ok( $s = $t->add_stemma( dotfile => 't/data/simple.dot' ), "Added a simple stemma" ); -is( ref( $s ), 'Text::Tradition::Stemma', "Got a stemma object returned" ); -is( $t->stemma_count, 1, "Tradition claims to have a stemma" ); -is( $t->stemma(0), $s, "Tradition hands back the right stemma" ); -} - - - 1; diff --git a/t/text_tradition_collation.t b/base/t/text_tradition_collation.t similarity index 91% rename from t/text_tradition_collation.t rename to base/t/text_tradition_collation.t index fc7abe1..f1bcba4 100644 --- a/t/text_tradition_collation.t +++ b/base/t/text_tradition_collation.t @@ -53,6 +53,7 @@ is( $c->reading('n21p0')->text, 'unto', "Reading n21p0 merged correctly" ); # =begin testing { use Text::Tradition; +use TryCatch; my $READINGS = 311; my $PATHS = 361; @@ -86,11 +87,20 @@ is( scalar $st->collation->paths, $PATHS, "Reparsed collation has all paths" ); is( scalar $st->collation->relationships, 3, "Reparsed collation has new relationships" ); # Now add a stemma, write to GraphML, and look at the output. -my $stemma = $tradition->add_stemma( 'dotfile' => 't/data/florilegium.dot' ); -is( ref( $stemma ), 'Text::Tradition::Stemma', "Parsed dotfile into stemma" ); -is( $tradition->stemmata, 1, "Tradition now has the stemma" ); -$graphml = $c->as_graphml; -like( $graphml, qr/digraph/, "Digraph declaration exists in GraphML" ); +my $SKIP_STEMMA; +try { + $tradition->enable_stemmata; +} catch { + $SKIP_STEMMA = 1; +} +SKIP: { + skip "Analysis module not present", 3 if $SKIP_STEMMA; + my $stemma = $tradition->add_stemma( 'dotfile' => 't/data/florilegium.dot' ); + is( ref( $stemma ), 'Text::Tradition::Stemma', "Parsed dotfile into stemma" ); + is( $tradition->stemmata, 1, "Tradition now has the stemma" ); + $graphml = $c->as_graphml; + like( $graphml, qr/digraph/, "Digraph declaration exists in GraphML" ); +} # Now add a user, write to GraphML, and look at the output. unlike( $graphml, qr/testuser/, "Test user name does not exist in GraphML yet" ); diff --git a/t/text_tradition_collation_relationshipstore.t b/base/t/text_tradition_collation_relationshipstore.t similarity index 100% rename from t/text_tradition_collation_relationshipstore.t rename to base/t/text_tradition_collation_relationshipstore.t diff --git a/t/text_tradition_directory.t b/base/t/text_tradition_directory.t similarity index 55% rename from t/text_tradition_directory.t rename to base/t/text_tradition_directory.t index 8950148..1eaa598 100644 --- a/t/text_tradition_directory.t +++ b/base/t/text_tradition_directory.t @@ -10,6 +10,7 @@ $| = 1; { use TryCatch; use File::Temp; +use Safe::Isa; use Text::Tradition; use_ok 'Text::Tradition::Directory'; @@ -23,26 +24,31 @@ my $t = Text::Tradition->new( 'input' => 'Tabular', 'file' => 't/data/simple.txt', ); +my $stemma_enabled; +eval { $stemma_enabled = $t->enable_stemmata; }; { my $d = Text::Tradition::Directory->new( 'dsn' => $dsn, 'extra_args' => { 'create' => 1 } ); - is( ref $d, 'Text::Tradition::Directory', "Got directory object" ); + ok( $d->$_isa('Text::Tradition::Directory'), "Got directory object" ); my $scope = $d->new_scope; $uuid = $d->save( $t ); ok( $uuid, "Saved test tradition" ); - my $s = $t->add_stemma( dotfile => 't/data/simple.dot' ); - ok( $d->save( $t ), "Updated tradition with stemma" ); - is( $d->tradition( $uuid ), $t, "Correct tradition returned for id" ); - is( $d->tradition( $uuid )->stemma(0), $s, "...and it has the correct stemma" ); - try { - $d->save( $s ); - } catch( Text::Tradition::Error $e ) { - is( $e->ident, 'database error', "Got exception trying to save stemma directly" ); - like( $e->message, qr/Cannot directly save non-Tradition object/, - "Exception has correct message" ); + SKIP: { + skip "Analysis package not installed", 5 unless $stemma_enabled; + my $s = $t->add_stemma( dotfile => 't/data/simple.dot' ); + ok( $d->save( $t ), "Updated tradition with stemma" ); + is( $d->tradition( $uuid ), $t, "Correct tradition returned for id" ); + is( $d->tradition( $uuid )->stemma(0), $s, "...and it has the correct stemma" ); + try { + $d->save( $s ); + } catch( Text::Tradition::Error $e ) { + is( $e->ident, 'database error', "Got exception trying to save stemma directly" ); + like( $e->message, qr/Cannot directly save non-Tradition object/, + "Exception has correct message" ); + } } } my $nt = Text::Tradition->new( @@ -50,7 +56,7 @@ my $nt = Text::Tradition->new( 'input' => 'CollateX', 'file' => 't/data/Collatex-16.xml', ); -is( ref( $nt ), 'Text::Tradition', "Made new tradition" ); +ok( $nt->$_isa('Text::Tradition'), "Made new tradition" ); { my $f = Text::Tradition::Directory->new( 'dsn' => $dsn ); @@ -64,24 +70,28 @@ is( ref( $nt ), 'Text::Tradition', "Made new tradition" ); my( $tlobj ) = grep { $_->{'id'} eq $uuid } @tlist; is( $tlobj->{'name'}, $tf->name, "Directory index has correct tradition name" ); is( $tf->name, $t->name, "Retrieved the tradition from a new directory" ); - my $sid = $f->object_to_id( $tf->stemma(0) ); - try { - $f->tradition( $sid ); - } catch( Text::Tradition::Error $e ) { - is( $e->ident, 'database error', "Got exception trying to fetch stemma directly" ); - like( $e->message, qr/not a Text::Tradition/, "Exception has correct message" ); - } - try { - $f->delete( $sid ); - } catch( Text::Tradition::Error $e ) { - is( $e->ident, 'database error', "Got exception trying to delete stemma directly" ); - like( $e->message, qr/Cannot directly delete non-Tradition object/, - "Exception has correct message" ); + my $sid; + SKIP: { + skip "Analysis package not installed", 4 unless $stemma_enabled; + $sid = $f->object_to_id( $tf->stemma(0) ); + try { + $f->tradition( $sid ); + } catch( Text::Tradition::Error $e ) { + is( $e->ident, 'database error', "Got exception trying to fetch stemma directly" ); + like( $e->message, qr/not a Text::Tradition/, "Exception has correct message" ); + } + try { + $f->delete( $sid ); + } catch( Text::Tradition::Error $e ) { + is( $e->ident, 'database error', "Got exception trying to delete stemma directly" ); + like( $e->message, qr/Cannot directly delete non-Tradition object/, + "Exception has correct message" ); + } } $f->delete( $uuid ); ok( !$f->exists( $uuid ), "Object is deleted from DB" ); - ok( !$f->exists( $sid ), "Object stemma also deleted from DB" ); + ok( !$f->exists( $sid ), "Object stemma also deleted from DB" ) if $stemma_enabled; is( scalar $f->traditionlist, 1, "Object is deleted from index" ); } diff --git a/t/text_tradition_language_armenian.t b/base/t/text_tradition_language_armenian.t similarity index 100% rename from t/text_tradition_language_armenian.t rename to base/t/text_tradition_language_armenian.t diff --git a/t/text_tradition_language_english.t b/base/t/text_tradition_language_english.t similarity index 100% rename from t/text_tradition_language_english.t rename to base/t/text_tradition_language_english.t diff --git a/t/text_tradition_language_french.t b/base/t/text_tradition_language_french.t similarity index 100% rename from t/text_tradition_language_french.t rename to base/t/text_tradition_language_french.t diff --git a/t/text_tradition_language_greek.t b/base/t/text_tradition_language_greek.t similarity index 100% rename from t/text_tradition_language_greek.t rename to base/t/text_tradition_language_greek.t diff --git a/t/text_tradition_language_latin.t b/base/t/text_tradition_language_latin.t similarity index 100% rename from t/text_tradition_language_latin.t rename to base/t/text_tradition_language_latin.t diff --git a/t/text_tradition_parser_collatex.t b/base/t/text_tradition_parser_collatex.t similarity index 100% rename from t/text_tradition_parser_collatex.t rename to base/t/text_tradition_parser_collatex.t diff --git a/t/text_tradition_parser_json.t b/base/t/text_tradition_parser_json.t similarity index 100% rename from t/text_tradition_parser_json.t rename to base/t/text_tradition_parser_json.t diff --git a/t/text_tradition_parser_self.t b/base/t/text_tradition_parser_self.t similarity index 74% rename from t/text_tradition_parser_self.t rename to base/t/text_tradition_parser_self.t index 5583932..35aa695 100644 --- a/t/text_tradition_parser_self.t +++ b/base/t/text_tradition_parser_self.t @@ -9,8 +9,10 @@ $| = 1; # =begin testing { use File::Temp; +use Safe::Isa; use Test::Warn; use Text::Tradition; +use TryCatch; binmode STDOUT, ":utf8"; binmode STDERR, ":utf8"; eval { no warnings; binmode $DB::OUT, ":utf8"; }; @@ -22,7 +24,7 @@ my $t = Text::Tradition->new( 'file' => $tradition, ); -is( ref( $t ), 'Text::Tradition', "Parsed GraphML version 2" ); +ok( $t->$_isa('Text::Tradition'), "Parsed GraphML version 2" ); if( $t ) { is( scalar $t->collation->readings, 319, "Collation has all readings" ); is( scalar $t->collation->paths, 376, "Collation has all paths" ); @@ -32,7 +34,15 @@ if( $t ) { # TODO add a relationship, add a stemma, write graphml, reparse it, check that # the new data is there $t->language('Greek'); -$t->add_stemma( 'dotfile' => 't/data/florilegium.dot' ); +my $stemma_enabled; +try { + $stemma_enabled = $t->enable_stemmata; +} catch { + ok( 1, "Skipping stemma tests without Analysis module" ); +} +if( $stemma_enabled ) { + $t->add_stemma( 'dotfile' => 't/data/florilegium.dot' ); +} $t->collation->add_relationship( 'w12', 'w13', { 'type' => 'grammatical', 'scope' => 'global', 'annotation' => 'This is some note' } ); @@ -40,7 +50,7 @@ ok( $t->collation->get_relationship( 'w12', 'w13' ), "Relationship set" ); my $graphml_str = $t->collation->as_graphml; my $newt = Text::Tradition->new( 'input' => 'Self', 'string' => $graphml_str ); -is( ref( $newt ), 'Text::Tradition', "Parsed current GraphML version" ); +ok( $newt->$_isa('Text::Tradition'), "Parsed current GraphML version" ); if( $newt ) { is( scalar $newt->collation->readings, 319, "Collation has all readings" ); is( scalar $newt->collation->paths, 376, "Collation has all paths" ); @@ -50,8 +60,10 @@ if( $newt ) { my $rel = $newt->collation->get_relationship( 'w12', 'w13' ); ok( $rel, "Found set relationship" ); is( $rel->annotation, 'This is some note', "Relationship has its properties" ); - is( scalar $newt->stemmata, 1, "Tradition has its stemma" ); - is( $newt->stemma(0)->witnesses, $t->stemma(0)->witnesses, "Stemma has correct length witness list" ); + if( $stemma_enabled ) { + is( scalar $newt->stemmata, 1, "Tradition has its stemma" ); + is( $newt->stemma(0)->witnesses, $t->stemma(0)->witnesses, "Stemma has correct length witness list" ); + } } # Test user save / restore @@ -63,7 +75,7 @@ my $userstore = Text::Tradition::Directory->new( { dsn => $dsn, extra_args => { create => 1 } } ); my $scope = $userstore->new_scope(); my $testuser = $userstore->create_user( { url => 'http://example.com' } ); -is( ref( $testuser ), 'Text::Tradition::User', "Created test user via userstore" ); +ok( $testuser->$_isa('Text::Tradition::User'), "Created test user via userstore" ); $testuser->add_tradition( $newt ); is( $newt->user->id, $testuser->id, "Assigned tradition to test user" ); $graphml_str = $newt->collation->as_graphml; @@ -75,6 +87,15 @@ warning_is { $usert = Text::Tradition->new( 'input' => 'Self', 'string' => $graphml_str, 'userstore' => $userstore ); is( $usert->user->id, $testuser->id, "Parsed tradition with userstore points to correct user" ); + +# Test warning if we can +unless( $stemma_enabled ) { + my $nst; + warnings_exist { + $nst = Text::Tradition->new( 'input' => 'Self', 'file' => 't/data/lexformat.xml' ); + } [qr/DROPPING stemmata/], + "Got expected stemma drop warning on parse"; +} } diff --git a/t/text_tradition_parser_tabular.t b/base/t/text_tradition_parser_tabular.t similarity index 100% rename from t/text_tradition_parser_tabular.t rename to base/t/text_tradition_parser_tabular.t diff --git a/t/text_tradition_parser_tei.t b/base/t/text_tradition_parser_tei.t similarity index 100% rename from t/text_tradition_parser_tei.t rename to base/t/text_tradition_parser_tei.t diff --git a/t/text_tradition_user.t b/base/t/text_tradition_user.t similarity index 100% rename from t/text_tradition_user.t rename to base/t/text_tradition_user.t diff --git a/t/text_tradition_user_collapse.t b/base/t/text_tradition_user_collapse.t similarity index 100% rename from t/text_tradition_user_collapse.t rename to base/t/text_tradition_user_collapse.t diff --git a/t/text_tradition_witness.t b/base/t/text_tradition_witness.t similarity index 100% rename from t/text_tradition_witness.t rename to base/t/text_tradition_witness.t