summaryrefslogtreecommitdiffstats
path: root/testing/runtests.pl
diff options
context:
space:
mode:
authorDimitri van Heesch <dimitri@stack.nl>2013-07-19 19:46:35 (GMT)
committerDimitri van Heesch <dimitri@stack.nl>2013-07-19 19:46:35 (GMT)
commit5875da6cae352bbcbe64f537ccfcfab08ad98b3f (patch)
tree1f707443b228c25e2d0389133b8e697e88a11426 /testing/runtests.pl
parentea7a639c40a88c0de4baad4c0ffd5ae4b4065969 (diff)
downloadDoxygen-5875da6cae352bbcbe64f537ccfcfab08ad98b3f.zip
Doxygen-5875da6cae352bbcbe64f537ccfcfab08ad98b3f.tar.gz
Doxygen-5875da6cae352bbcbe64f537ccfcfab08ad98b3f.tar.bz2
Added regression test suite
Diffstat (limited to 'testing/runtests.pl')
-rwxr-xr-xtesting/runtests.pl252
1 files changed, 252 insertions, 0 deletions
diff --git a/testing/runtests.pl b/testing/runtests.pl
new file mode 100755
index 0000000..bbbd1be
--- /dev/null
+++ b/testing/runtests.pl
@@ -0,0 +1,252 @@
+#!/usr/bin/perl
+
+# perl script to execute doxygen's regression test suite.
+#
+# Copyright (C) 1997-2013 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+
+use strict;
+use warnings;
+
+use Getopt::Long;
+use Test::More;
+use File::Path qw(make_path remove_tree);
+use File::Copy qw(copy);
+
+my $Test = Test::Builder->new;
+my $opt_doxygen_exe = 'doxygen';
+my $opt_xmllint_exe = 'xmllint';
+my $opt_updateref = '';
+my @opt_test_ids;
+my $opt_all = '';
+
+GetOptions( 'updateref' => \$opt_updateref,
+ 'doxygen=s' => \$opt_doxygen_exe,
+ 'xmllint=s' => \$opt_xmllint_exe,
+ 'id=i' => \@opt_test_ids,
+ 'all' => \$opt_all
+ );
+
+sub read_two_files {
+ my $first = shift;
+ my $second = shift;
+ my $filter = shift;
+ my $success = 1;
+ my @errors;
+
+ unless (open FIRST, "$first") {
+ $success = 0;
+ push @errors, "$first absent";
+ }
+ unless (open SECOND, "$second") {
+ $success = 0;
+ push @errors, "$second absent";
+ }
+ return ($success, @errors) unless $success;
+
+ my $first_lines = join "",<FIRST>;
+ my $second_lines = join "",<SECOND>;
+
+ close FIRST;
+ close SECOND;
+
+ return ($success, $first_lines, $second_lines);
+}
+
+sub compare_ok {
+ my $got_file = shift;
+ my $expected_file = shift;
+ my $name = shift;
+ my @read_result = read_two_files($got_file, $expected_file);
+ my $files_exist = shift @read_result;
+
+ if ($files_exist) {
+ my ($got, $expected) = @read_result;
+ my $diff = `diff -u $got_file $expected_file`;
+ my $failed = length $diff;
+ return ($failed,"Difference between generated output and reference:\n$diff");
+ }
+ else {
+ return (1,join "\n", @read_result);
+ }
+}
+
+sub chop_volatile {
+ my $line = shift;
+ $line =~ s/version="\d\.\d.\d+"/version=""/g; # strip version
+ $line =~ s/file=".*\/(.*)"/file="$1"/g; # strip location
+ return $line;
+}
+
+sub get_config {
+ my $file = shift;
+ my %config;
+ open F,"<$file";
+ while (<F>) {
+ if (/\/\/\s*(\S+):\s*(.*)$/) {
+ my $key = $1;
+ my $val = $2;
+ chomp $val;
+ $config{$key} = [] unless defined $config{$key};
+ push @{$config{$key}},$val;
+ }
+ }
+ return %config;
+}
+
+sub perform_test {
+ my $test_file = shift;
+ my %config = get_config($test_file);
+ my $test_name = "[$test_file]: $config{'objective'}[0]";
+ my $test_id = $test_file;
+ $test_id =~ s/^(\d+).*$/$1/;
+ my $test_out = "test_output_${test_id}";
+
+ if (scalar($config{'check'})==0) {
+ $Test->ok(0, $test_name);
+ $Test->diag("Test doesn't specify any files to check");
+ return;
+ }
+
+ # prepare test environment
+ remove_tree("$test_out");
+ make_path("$test_out");
+ copy("Doxyfile","$test_out");
+ open(F,">>$test_out/Doxyfile");
+ print F "INPUT = $test_file\n";
+ print F "XML_OUTPUT = $test_out/out\n";
+ foreach my $cfg (@{$config{'config'}}) {
+ print F "$cfg\n";
+ }
+ close(F);
+
+ # run doxygen
+ if (system("$opt_doxygen_exe $test_out/Doxyfile")!=0) {
+ $Test->ok(0, $test_name);
+ $Test->diag("Failed to run doxygen");
+ return;
+ }
+
+ # look for files to check against the reference
+ foreach my $fn (@{$config{'check'}}) {
+ if (!-f "$test_out/out/$fn") {
+ $Test->ok(0, $test_name);
+ $Test->diag("Non-existing file $test_out/out/$fn after 'check:' statement");
+ return;
+ }
+ # run xmllint on the output file
+ my @lines = `$opt_xmllint_exe --format --noblanks --nowarning $test_out/out/$fn`;
+ if (scalar(@lines)>0 && open(F,">$test_out/$fn")) {
+ foreach my $line (@lines) {
+ print F chop_volatile($line);
+ }
+ close(F);
+ } else {
+ $Test->ok(0, $test_name);
+ $Test->diag("Failed to run xmllint on the doxygen output file $test_out/out/$fn");
+ }
+ my ($failed,$msg) = compare_ok("$test_out/$fn","$test_id/$fn",$test_name);
+ if ($failed) {
+ $Test->ok(0, $test_name);
+ $Test->diag($msg);
+ return;
+ }
+ }
+
+ # test passed
+ remove_tree("$test_out");
+ $Test->ok(1, $test_name);
+}
+
+sub update_test {
+ my $test_file = shift;
+ my %config = get_config($test_file);
+ my $test_name = "[$test_file]: $config{'objective'}[0]";
+ my $test_id = $test_file;
+ $test_id =~ s/^(\d+).*$/$1/;
+ my $test_out = $test_id;
+
+ # prepare reference environment
+ remove_tree("$test_out");
+ make_path("$test_out");
+ copy("Doxyfile","$test_out");
+ open(F,">>$test_out/Doxyfile");
+ print F "INPUT = $test_file\n";
+ print F "XML_OUTPUT = $test_out/out\n";
+ foreach my $cfg (@{$config{'config'}}) {
+ print F "$cfg\n";
+ }
+ close(F);
+
+ print "Updating reference for $test_name\n";
+
+ # run doxygen
+ if (system("$opt_doxygen_exe $test_out/Doxyfile")!=0) {
+ print("Error: failed to run doxygen");
+ return;
+ }
+ my $err=0;
+
+ # look for files to prepare as reference
+ foreach my $fn (@{$config{'check'}}) {
+ if (!-f "$test_out/out/$fn") {
+ printf("Error: Non-existing file $test_out/out/$fn after 'check:' statement\n");
+ $err=1;
+ }
+ # run xmllint on the output file
+ if (!$err) {
+ my @lines = `$opt_xmllint_exe --format --noblanks --nowarning $test_out/out/$fn`;
+ if (scalar(@lines)>0 && open(F,">$test_out/$fn")) {
+ foreach my $line (@lines) {
+ print F chop_volatile($line);
+ }
+ close(F);
+ } else {
+ printf("Error: Failed to run xmllint on the doxygen output file $test_out/out/$fn\n");
+ $err=1;
+ }
+ }
+ }
+
+ if (!$err) {
+ # clean-up
+ remove_tree("$test_out/out");
+ unlink("$test_out/Doxyfile");
+ }
+}
+
+# get the tests
+my @tests;
+if (scalar(@opt_test_ids)==0 && $opt_updateref && !$opt_all) {
+ printf("Error: updateref option requires -id to update a test or -all to update all\n");
+ exit(1);
+}
+if (scalar(@opt_test_ids)>0) {
+ foreach my $t (@opt_test_ids) {
+ push @tests, glob("${t}_* 0${t}_* 00${t}_*");
+ }
+} else {
+ @tests = glob('[0-9][0-9][0-9]_*');
+}
+
+if ($opt_updateref) {
+ # update reference
+ foreach my $test (@tests) {
+ update_test($test);
+ }
+} else {
+ # run tests
+ plan tests => scalar(@tests);
+ foreach my $test (@tests) {
+ perform_test($test);
+ }
+}
+