1#!/usr/bin/perl -w 2# ----------------------------------------------------------------------------- 3 4use strict; 5use lib ($0 =~ m|^(.*/)| ? $1 : "."); 6use GnumericTest; 7 8my %extras = 9 ('xml.xsd' => 'http://www.w3.org/2009/01/xml.xsd' 10 ); 11 12 13&message ("Check that the xlsx exporter produces valid files."); 14 15my $format = "Gnumeric_Excel:xlsx"; 16# FIXME: until get figure out how to check xlsx files against a schema, 17# this is a very limited test. 18my $schema = "$topsrc/test/ooxml-schema/sml.xsd"; 19if (!-r $schema) { 20 &message ("Schema $schema not found"); 21 $schema = undef; 22} 23my $chart_schema = "$topsrc/test/ooxml-schema/dml-chart.xsd"; 24if (!-r $chart_schema) { 25 &message ("Schema $chart_schema not found"); 26 $chart_schema = undef; 27} 28my $drawing_schema = "$topsrc/test/ooxml-schema/dml-spreadsheetDrawing.xsd"; 29if (!-r $drawing_schema) { 30 &message ("Schema $drawing_schema not found"); 31 $drawing_schema = undef; 32} 33 34my $xmllint_extra = "$topsrc/test/xmllint-extra"; 35for my $extra (sort keys %extras) { 36 my $f = "$xmllint_extra/$extra"; 37 &GnumericTest::report_skip ("Missing $f available from $extras{$extra}") 38 unless -r $f; 39} 40 41my $sml_schema_patched_for_comments = undef; 42my $sml_schema_patched_for_comments_warned = 0; 43if ($schema) { 44 system ("grep", "-q", "-w", "CT_Text", $schema); 45 $sml_schema_patched_for_comments = ($? == 0); 46} 47 48my $xmllint = &GnumericTest::find_program ("xmllint"); 49my $unzip = &GnumericTest::find_program ("unzip"); 50 51my @sources = &GnumericTest::corpus(); 52# xmllint hangs on these files. (Well, amath finishes but takes too 53# long.) 54@sources = grep { !m{(^|/)(amath|crlibm|gamma)\.gnumeric$} } @sources; 55 56my $nskipped = 0; 57my $ngood = 0; 58my $nbad = 0; 59 60my $common_checker = "$xmllint --noout --nonet --path $xmllint_extra"; 61 62my $checker = $common_checker . ($schema ? " --schema $schema" : ""); 63my $chart_checker = $common_checker . ($chart_schema ? " --schema $chart_schema" : ""); 64my $drawing_checker = $common_checker . ($drawing_schema ? " --schema $drawing_schema" : ""); 65my $basic_checker = $common_checker; 66 67my %checkers = ( 0 => $checker, 68 1 => $chart_checker, 69 2 => $drawing_checker, 70 -1 => $basic_checker); 71 72foreach my $src (@sources) { 73 if (!-r $src) { 74 $nskipped++; 75 next; 76 } 77 78 print STDERR "Checking $src\n"; 79 80 my $tmp = $src; 81 $tmp =~ s|^.*/||; 82 $tmp =~ s|\..*|.xlsx|; 83 &GnumericTest::junkfile ($tmp); 84 85 { 86 my $cmd = &GnumericTest::quotearg ($ssconvert, '-T', $format, $src, $tmp); 87 print STDERR "# $cmd\n" if $GnumericTest::verbose; 88 system ($cmd); 89 if (!-r $tmp) { 90 print STDERR "ssconvert failed to produce $tmp\n"; 91 die "Fail\n"; 92 } 93 } 94 95 my %members; 96 foreach (`$unzip -v $tmp`) { 97 next unless /^----/ ... /^----/; 98 next unless m{^\s*\d.*\s(\S+)$}; 99 my $member = $1; 100 if (exists $members{$member}) { 101 print STDERR "Duplicate member $member\n"; 102 die "Fail\n"; 103 } 104 $members{$member} = 1; 105 } 106 107 my @check_members = (['xl/workbook.xml',0] , ['xl/styles.xml', 0]); 108 push @check_members, ['xl/sharedStrings.xml',0] if $members{'xl/sharedStrings.xml'}; 109 foreach my $member (sort keys %members) { 110 if ($member =~ m{^xl/worksheets/sheet\d+\.xml$}) { 111 push @check_members, [$member,0] 112 } elsif ($member =~ m{^xl/comments\d+\.xml$}) { 113 if ($sml_schema_patched_for_comments) { 114 push @check_members, [$member,0]; 115 } else { 116 if (!$sml_schema_patched_for_comments_warned) { 117 $sml_schema_patched_for_comments_warned = 1; 118 &message ("Comment checking requires a patched schema, see bug 790756."); 119 } 120 push @check_members, [$member,-1]; 121 } 122 } elsif ($member =~ m{^xl/charts/chart\d+\.xml$}) { 123 push @check_members, [$member,1]; 124 } elsif ($member =~ m{^xl/drawings/drawing\d+\.xml$}) { 125 push @check_members, [$member,2]; 126 } elsif ($member =~ m{^[-a-zA-Z0-0_/.]+\.xml$}) { 127 push @check_members, [$member,-1]; 128 } elsif ($member =~ m{^[-a-zA-Z0-0_/.]+\.rels$}) { 129 push @check_members, [$member,-1]; 130 } 131 } 132 133 for (@check_members) { 134 my ($member,$typ) = @$_; 135 my $this_checker = $checkers{$typ}; 136 my $cmd = "$unzip -p $tmp '$member' | $this_checker -"; 137 print STDERR "# $cmd\n" if $GnumericTest::verbose; 138 my $out = `$cmd 2>&1`; 139 if ($out ne '' && $out !~ /validates$/) { 140 print STDERR "While checking $member from $tmp:\n"; 141 &GnumericTest::dump_indented ($out); 142 $nbad++; 143 } else { 144 $ngood++; 145 } 146 } 147 148 &GnumericTest::removejunk ($tmp); 149} 150 151&GnumericTest::report_skip ("No source files present") if $nbad + $ngood == 0; 152 153if ($nskipped > 0) { 154 print STDERR "$nskipped files skipped.\n"; 155} 156 157if ($nbad > 0) { 158 die "Fail\n"; 159} else { 160 print STDERR "Pass\n"; 161} 162