bzr branch
/bmo/3.4
| Line | Revision | Contents |
| 1 | 4038 | # -*- Mode: perl; indent-tabs-mode: nil -*- |
| 2 | # vim: ts=4 sw=4 et tw=80 |
|
| 3 | # |
|
| 4 | # The contents of this file are subject to the Mozilla Public |
|
| 5 | # License Version 1.1 (the "License"); you may not use this file |
|
| 6 | # except in compliance with the License. You may obtain a copy of |
|
| 7 | # the License at http://www.mozilla.org/MPL/ |
|
| 8 | # |
|
| 9 | # Software distributed under the License is distributed on an "AS |
|
| 10 | # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
|
| 11 | # implied. See the License for the specific language governing |
|
| 12 | # rights and limitations under the License. |
|
| 13 | # |
|
| 14 | # The Original Code are the Bugzilla Tests. |
|
| 15 | # |
|
| 16 | # The Initial Developer of the Original Code is Zach Lipton |
|
| 17 | # Portions created by Zach Lipton are |
|
| 18 | # Copyright (C) 2001 Zach Lipton. All |
|
| 19 | # Rights Reserved. |
|
| 20 | # |
|
| 21 | # Contributor(s): Dennis Melentyev <dennis.melentyev@infopulse.com.ua> |
|
| 22 | 4594 | # Max Kanat-Alexander <mkanat@bugzilla.org> |
| 23 | 4038 | |
| 24 | ||
| 25 | ||
| 26 | ################## |
|
| 27 | #Bugzilla Test 12# |
|
| 28 | ######Errors###### |
|
| 29 | ||
| 30 | use strict; |
|
| 31 | ||
| 32 | use lib 't'; |
|
| 33 | ||
| 34 | 4594 | use Bugzilla::WebService::Constants; |
| 35 | ||
| 36 | 4038 | use File::Spec; |
| 37 | use Support::Files; |
|
| 38 | use Support::Templates; |
|
| 39 | use Test::More; |
|
| 40 | ||
| 41 | my %Errors = (); |
|
| 42 | ||
| 43 | # Just a workaround for template errors handling. Define it as used. |
|
| 44 | push @{$Errors{code}{template_error}{used_in}{'Bugzilla/Error.pm'}}, 0; |
|
| 45 | ||
| 46 | # Define files to test. Each file would have a list of error messages, if any. |
|
| 47 | my %test_templates = (); |
|
| 48 | my %test_modules = (); |
|
| 49 | ||
| 50 | # Find all modules |
|
| 51 | foreach my $module (@Support::Files::testitems) { |
|
| 52 | $test_modules{$module} = (); |
|
| 53 | } |
|
| 54 | ||
| 55 | # Find all error templates |
|
| 56 | # Process all files since otherwise handling template hooks would became too |
|
| 57 | # hairy. But let us do it only once. |
|
| 58 | ||
| 59 | foreach my $include_path (@include_paths) { |
|
| 60 | foreach my $path (@{$actual_files{$include_path}}) { |
|
| 61 | my $file = File::Spec->catfile($include_path, $path); |
|
| 62 | $file =~ s/\s.*$//; # nuke everything after the first space |
|
| 63 | $file =~ s|\\|/|g if $^O eq 'MSWin32'; # convert \ to / in path if on windows |
|
| 64 | $test_templates{$file} = () |
|
| 65 | 4132 | if $file =~ m#global/(code|user)-error\.html\.tmpl#; |
| 66 | 4038 | } |
| 67 | } |
|
| 68 | ||
| 69 | 4594 | # Count the tests. The +1 is for checking the WS_ERROR_CODE errors. |
| 70 | my $tests = (scalar keys %test_modules) + (scalar keys %test_templates) + 1; |
|
| 71 | 4038 | exit 0 if !$tests; |
| 72 | ||
| 73 | # Set requested tests counter. |
|
| 74 | plan tests => $tests; |
|
| 75 | ||
| 76 | # Collect all errors defined in templates |
|
| 77 | foreach my $file (keys %test_templates) { |
|
| 78 | $file =~ m|template/([^/]+).*/global/([^/]+)-error\.html\.tmpl|; |
|
| 79 | my $lang = $1; |
|
| 80 | my $errtype = $2; |
|
| 81 | ||
| 82 | if (! open (TMPL, $file)) { |
|
| 83 | Register(\%test_templates, $file, "could not open file --WARNING"); |
|
| 84 | next; |
|
| 85 | } |
|
| 86 | ||
| 87 | my $lineno=0; |
|
| 88 | while (my $line = <TMPL>) { |
|
| 89 | $lineno++; |
|
| 90 | if ($line =~ /\[%\s[A-Z]+\s*error\s*==\s*"(.+)"\s*%\]/) { |
|
| 91 | my $errtag = $1; |
|
| 92 | if ($errtag =~ /\s/) { |
|
| 93 | Register(\%test_templates, $file, |
|
| 94 | 4155 | "has an error definition \"$errtag\" at line $lineno with " |
| 95 | 4038 | . "space(s) embedded --ERROR"); |
| 96 | } |
|
| 97 | else { |
|
| 98 | push @{$Errors{$errtype}{$errtag}{defined_in}{$lang}{$file}}, $lineno; |
|
| 99 | } |
|
| 100 | } |
|
| 101 | } |
|
| 102 | close(TMPL); |
|
| 103 | } |
|
| 104 | ||
| 105 | # Collect all used errors from cgi/pm files |
|
| 106 | foreach my $file (keys %test_modules) { |
|
| 107 | $file =~ s/\s.*$//; # nuke everything after the first space (#comment) |
|
| 108 | next if (!$file); # skip null entries |
|
| 109 | if (! open (TMPL, $file)) { |
|
| 110 | Register(\%test_modules, $file, "could not open file --WARNING"); |
|
| 111 | next; |
|
| 112 | } |
|
| 113 | ||
| 114 | my $lineno = 0; |
|
| 115 | while (my $line = <TMPL>) { |
|
| 116 | last if $line =~ /^__END__/; # skip the POD (at least in |
|
| 117 | # Bugzilla/Error.pm) |
|
| 118 | $lineno++; |
|
| 119 | 4166 | if ($line =~ |
| 120 | /^[^#]*(Throw(Code|User)Error|error\s+=>)\s*\(?\s*["'](.*?)['"]/) { |
|
| 121 | my $errtype; |
|
| 122 | # If it's a normal ThrowCode/UserError |
|
| 123 | if ($2) { |
|
| 124 | $errtype = lc($2); |
|
| 125 | } |
|
| 126 | # If it's an AUTH_ERROR tag |
|
| 127 | else { |
|
| 128 | $errtype = 'code'; |
|
| 129 | } |
|
| 130 | my $errtag = $3; |
|
| 131 | 4038 | push @{$Errors{$errtype}{$errtag}{used_in}{$file}}, $lineno; |
| 132 | } |
|
| 133 | } |
|
| 134 | ||
| 135 | close(TMPL); |
|
| 136 | } |
|
| 137 | ||
| 138 | # Now let us start the checks |
|
| 139 | ||
| 140 | foreach my $errtype (keys %Errors) { |
|
| 141 | foreach my $errtag (keys %{$Errors{$errtype}}) { |
|
| 142 | # Check for undefined tags |
|
| 143 | if (!defined $Errors{$errtype}{$errtag}{defined_in}) { |
|
| 144 | UsedIn($errtype, $errtag, "any"); |
|
| 145 | } |
|
| 146 | else { |
|
| 147 | # Check for all languages!!! |
|
| 148 | my @langs = (); |
|
| 149 | foreach my $lang (@languages) { |
|
| 150 | if (!defined $Errors{$errtype}{$errtag}{defined_in}{$lang}) { |
|
| 151 | push @langs, $lang; |
|
| 152 | } |
|
| 153 | } |
|
| 154 | if (scalar @langs) { |
|
| 155 | UsedIn($errtype, $errtag, join(', ',@langs)); |
|
| 156 | } |
|
| 157 | ||
| 158 | # Now check for tag usage in all DEFINED languages |
|
| 159 | foreach my $lang (keys %{$Errors{$errtype}{$errtag}{defined_in}}) { |
|
| 160 | if (!defined $Errors{$errtype}{$errtag}{used_in}) { |
|
| 161 | DefinedIn($errtype, $errtag, $lang); |
|
| 162 | } |
|
| 163 | } |
|
| 164 | } |
|
| 165 | } |
|
| 166 | } |
|
| 167 | ||
| 168 | 4594 | # And make sure that everything defined in WS_ERROR_CODE |
| 169 | # is actually a valid error. |
|
| 170 | foreach my $err_name (keys %{WS_ERROR_CODE()}) { |
|
| 171 | if (!defined $Errors{'code'}{$err_name} |
|
| 172 | && !defined $Errors{'user'}{$err_name}) |
|
| 173 | { |
|
| 174 | Register(\%test_modules, 'WS_ERROR_CODE', |
|
| 175 | "Error tag '$err_name' is used in WS_ERROR_CODE in" |
|
| 176 | . " Bugzilla/WebService/Constants.pm" |
|
| 177 | . " but not defined in any template, and not used in any code."); |
|
| 178 | } |
|
| 179 | } |
|
| 180 | ||
| 181 | 4038 | # Now report modules results |
| 182 | foreach my $file (sort keys %test_modules) { |
|
| 183 | Report($file, @{$test_modules{$file}}); |
|
| 184 | } |
|
| 185 | ||
| 186 | 4594 | # And report WS_ERROR_CODE results |
| 187 | Report('WS_ERROR_CODE', @{$test_modules{'WS_ERROR_CODE'}}); |
|
| 188 | ||
| 189 | 4038 | # Now report templates results |
| 190 | foreach my $file (sort keys %test_templates) { |
|
| 191 | Report($file, @{$test_templates{$file}}); |
|
| 192 | } |
|
| 193 | ||
| 194 | sub Register { |
|
| 195 | 4155 | my ($hash, $file, $message, $warning) = @_; |
| 196 | # If set to 1, $warning will avoid the test to fail. |
|
| 197 | $warning ||= 0; |
|
| 198 | push(@{$hash->{$file}}, {'message' => $message, 'warning' => $warning}); |
|
| 199 | 4038 | } |
| 200 | ||
| 201 | sub Report { |
|
| 202 | my ($file, @errors) = @_; |
|
| 203 | if (scalar @errors) { |
|
| 204 | 4155 | # Do we only have warnings to report or also real errors? |
| 205 | my @real_errors = grep {$_->{'warning'} == 0} @errors; |
|
| 206 | # Extract error messages. |
|
| 207 | @errors = map {$_->{'message'}} @errors; |
|
| 208 | if (scalar(@real_errors)) { |
|
| 209 | ok(0, "$file has ". scalar(@errors) ." error(s):\n" . join("\n", @errors)); |
|
| 210 | } |
|
| 211 | else { |
|
| 212 | ok(1, "--WARNING $file has " . scalar(@errors) . |
|
| 213 | " unused error tag(s):\n" . join("\n", @errors)); |
|
| 214 | } |
|
| 215 | 4038 | } |
| 216 | else { |
|
| 217 | # This is used for both code and template files, so let's use |
|
| 218 | # file-independent phrase |
|
| 219 | ok(1, "$file uses error tags correctly"); |
|
| 220 | } |
|
| 221 | } |
|
| 222 | ||
| 223 | sub UsedIn { |
|
| 224 | my ($errtype, $errtag, $lang) = @_; |
|
| 225 | $lang = $lang || "any"; |
|
| 226 | foreach my $file (keys %{$Errors{$errtype}{$errtag}{used_in}}) { |
|
| 227 | Register(\%test_modules, $file, |
|
| 228 | "$errtype error tag '$errtag' is used at line(s) (" |
|
| 229 | . join (',', @{$Errors{$errtype}{$errtag}{used_in}{$file}}) |
|
| 230 | . ") but not defined for language(s): $lang"); |
|
| 231 | } |
|
| 232 | } |
|
| 233 | sub DefinedIn { |
|
| 234 | my ($errtype, $errtag, $lang) = @_; |
|
| 235 | foreach my $file (keys %{$Errors{$errtype}{$errtag}{defined_in}{$lang}}) { |
|
| 236 | Register(\%test_templates, $file, |
|
| 237 | "$errtype error tag '$errtag' is defined at line(s) (" |
|
| 238 | . join (',', @{$Errors{$errtype}{$errtag}{defined_in}{$lang}{$file}}) |
|
| 239 | 4155 | . ") but is not used anywhere", 1); |
| 240 | 4038 | } |
| 241 | } |
|
| 242 | ||
| 243 | exit 0; |
Loggerhead 1.18.1 is a web-based interface for Bazaar branches