1#!perl
2
3## Spellcheck as much as we can
4
5use 5.008;
6use strict;
7use warnings;
8use Test::More;
9use utf8;
10
11my (@testfiles, $fh);
12
13if (!$ENV{RELEASE_TESTING}) {
14    plan (skip_all =>  'Test skipped unless environment variable RELEASE_TESTING is set');
15}
16elsif (!eval { require Text::SpellChecker; 1 }) {
17    plan skip_all => 'Could not find Text::SpellChecker';
18}
19else {
20    opendir my $dir, 't' or die qq{Could not open directory 't': $!\n};
21    @testfiles = map { "t/$_" } grep { /^\d.+\.(t|pl|pm)$/ } readdir $dir;
22    closedir $dir or die qq{Could not closedir "$dir": $!\n};
23    plan tests => 3+@testfiles;
24}
25
26my %okword;
27my $filename = 'Common';
28while (<DATA>) {
29    if (/^## (.+):/) {
30        $filename = $1;
31        next;
32    }
33    next if /^#/ or ! /\w/;
34    for (split) {
35        $okword{$filename}{$_}++;
36    }
37}
38
39
40sub spellcheck {
41    my ($desc, $text, $file) = @_;
42    my $check = Text::SpellChecker->new(text => $text);
43    my %badword;
44    while (my $word = $check->next_word) {
45        next if $okword{Common}{$word} or $okword{$file}{$word};
46        $badword{$word}++;
47    }
48    my $count = keys %badword;
49    if (! $count) {
50        pass("Spell check passed for $desc");
51        return;
52    }
53    fail ("Spell check failed for $desc. Bad words: $count");
54    for (sort keys %badword) {
55        diag "$_\n";
56    }
57    return;
58}
59
60
61## The embedded POD
62SKIP: {
63    if (!eval { require Pod::Spell; 1 }) {
64        skip 'Need Pod::Spell to test the spelling of embedded POD', 1;
65    }
66
67    for my $file (qw{check_postgres.pl}) {
68        if (! -e $file) {
69            fail(qq{Could not find the file "$file"!});
70        }
71        my $string = qx{podspell $file};
72        spellcheck("POD from $file" => $string, $file);
73    }
74}
75
76
77## The embedded POD, round two, because the above does not catch everything
78SKIP: {
79    if (!eval { require Pod::Text; 1 }) {
80        skip 'Need Pod::Text to re-test the spelling of embedded POD', 1;
81    }
82
83    my $parser = Pod::Text->new (quotes => 'none', width => 400, utf8 => 1);
84
85    for my $file (qw{check_postgres.pl}) {
86        if (! -e $file) {
87            fail(qq{Could not find the file "$file"!});
88        }
89        my $string;
90        my $tmpfile = "$file.spellcheck.tmp";
91        $parser->parse_from_file($file, $tmpfile);
92        next if ! open my $fh, '<:encoding(UTF-8)', $tmpfile;
93        { local $/; $string = <$fh>; }
94        close $fh or warn "Could not close $tmpfile\n";
95        unlink $tmpfile;
96        spellcheck("POD inside $file" => $string, $file);
97    }
98}
99
100
101## Now the comments
102SKIP: {
103    if (!eval { require File::Comments; 1 }) {
104        skip 'Need File::Comments to test the spelling inside comments', 1+@testfiles;
105    }
106    my $fc = File::Comments->new();
107
108    my @files;
109    for (sort @testfiles) {
110        push @files, "$_";
111    }
112
113    for my $file (@testfiles, qw{check_postgres.pl}) {
114        if (! -e $file) {
115            fail(qq{Could not find the file "$file"!});
116        }
117        my $string = $fc->comments($file);
118        if (! $string) {
119            fail(qq{Could not get comments inside file $file});
120            next;
121        }
122        $string = join "\n" => @$string;
123        $string =~ s/=head1.+//sm;
124        spellcheck("comments from $file" => $string, $file);
125    }
126
127
128}
129
130
131__DATA__
132## These words are okay
133
134## Common:
135
136arrayref
137async
138autovac
139Backends
140backends
141bc
142bucardo
143checksum
144chroot
145commitratio
146consrc
147cp
148dbh
149dbstats
150df
151DBI
152DSN
153ENV
154filesystem
155fsm
156goto
157hitratio
158lsfunc
159Mullane
160Nagios
161ok
162PGP
163Postgres
164Sabino
165SQL
166http
167logfile
168login
169perl
170pgagent
171pgbouncer
172pgBouncer
173pgservice
174plpgsql
175postgres
176Pre
177runtime
178Schemas
179selectall
180skipcycled
181skipobject
182Slony
183slony
184stderr
185syslog
186tcl
187timestamp
188tnm
189txn
190txns
191turnstep
192tuples
193wal
194www
195zettabytes
196
197##99_spellcheck.t:
198
199Spellcheck
200textfiles
201
202## index.html:
203
204DOCTYPE
205DTD
206PGP
207XHTML
208asc
209css
210dtd
211endcrypt
212href
213html
214https
215lang
216li
217listinfo
218moz
219pre
220px
221ul
222xhtml
223xml
224xmlns
225
226## check_postgres.pl:
227
228Abrigo
229Adrien
230Ahlgren
231Ahlgren
232Albe
233alice
234Andras
235Andreas
236ARG
237args
238artemus
239Astill
240autoanalyze
241AUTOanalyze
242autovac
243autovacuum
244AUTOvacuum
245backends
246Basename
247battlestar
248baz
249bigint
250Blasco
251Blasco
252Brüssel
253blks
254Boes
255boxinfo
256Boxinfo
257Bracht
258Bracht
259Bucardo
260burrick
261cd
262checkpostgresrc
263checksum
264checksums
265checktype
266Cédric
267Christoph
268commitratio
269commitratio
270conf
271conn
272conn
273contrib
274controldata
275cperl
276criticals
277cronjob
278ctl
279CUUM
280Cwd
281cylon
282datadir
283datallowconn
284Davide
285dbhost
286dbname
287dbpass
288dbport
289dbservice
290dbstats
291dbuser
292de
293debugoutput
294Deckelmann
295del
296DESC
297dev
298df
299dir
300dric
301dylan
302EB
303Eisentraut
304Eloranta
305Eloranta
306Elsasser
307emma
308endcrypt
309EnterpriseDB
310env
311eval
312exabyte
313exabytes
314excludeuser
315excludeusers
316ExclusiveLock
317executables
318faceoff
319filename
320filenames
321filenames
322finishup
323flagg
324fooey
325franklin
326FreeBSD
327freespacemap
328fsm
329garrett
330Geert
331Geert
332Getopt
333GetOptions
334github
335github
336Glaesemann
337Glyn
338greg
339grimm
340GSM
341gtld
342Guettler
343Guillaume
344Gurjeet
345Hagander
346Hansper
347hardcode
348Henrik
349Henrik
350HiRes
351hitratio
352hitratio
353hitratio
354Holger
355hong
356HOSTADDRESS
357html
358https
359Hywel
360idx
361idxblkshit
362idxblkshit
363idxblksread
364idxblksread
365idxscan
366idxscan
367idxtupfetch
368idxtupfetch
369idxtupread
370idxtupread
371includeuser
372Ioannis
373ioguix
374Jacobo
375Jacobo
376Janes
377Jehan
378Jens
379Jürgen
380Kabalin
381Kirkwood
382klatch
383kong
384Koops
385Krishnamurthy
386lancre
387Laurenz
388Lelarge
389Lesouef
390libpq
391listinfo
392localhost
393localtime
394Logfile
395logtime
396Mager
397Magnus
398maindatabase
399Makefile
400Mallett
401mallory
402Marti
403maxalign
404maxwait
405mcp
406MERCHANTABILITY
407Mika
408Mika
409MINIPAGES
410MINPAGES
411minvalue
412Moench
413morpork
414mrtg
415MRTG
416msg
417multi
418nagios
419NAGIOS
420Nayrat
421Nenciarini
422nextval
423nnx
424nofuncbody
425nofunctions
426noidle
427noindexes
428nolanguage
429nols
430noname
431noname
432noobjectname
433noobjectnames
434noowner
435noperm
436noperms
437noposition
438noschema
439noschema
440notrigger
441ok
442Oliveira
443oper
444Optimizations
445oskar
446pageslots
447Pante
448Pante
449param
450parens
451Patric
452Patric
453perf
454perfdata
455perflimit
456perfname
457perfs
458petabytes
459pgAgent
460pgb
461PGBINDIR
462pgbouncer's
463PGCONTROLDATA
464PGDATA
465PGDATABASE
466PGHOST
467pgpass
468PGPORT
469PGSERVICE
470pgsql
471PGUSER
472pid
473Pirogov
474plasmid
475plugin
476pluto
477POSTGRES
478postgresql
479PostgreSQL
480postgresrc
481prepend
482prereqs
483psql
484PSQL
485queryname
486quirm
487Raudsepp
488rc
489Redistributions
490refactor
491refactoring
492regex
493regexes
494relallvisible
495relallvisible
496relminmxid
497relminmxid
498relname
499relpages
500Renner
501Renner
502repinfo
503RequireInterpolationOfMetachars
504ret
505ritical
506rgen
507robert
508Rorthais
509runtime
510Ruslan
511salesrep
512sami
513sb
514schemas
515scott
516sda
517Seklecki
518seqscan
519seqscan
520seqtupread
521seqtupread
522SETOF
523showperf
524Sijmons
525Singh
526Sivakumar
527sl
528slon
529slony
530Slony
531Slony's
532snazzo
533speedtest
534Sprickman
535Sprickman
536sql
537SQL
538ssel
539sslmode
540Stas
541stderr
542STDOUT
543sv
544symlink
545symlinked
546symlinks
547tablespace
548tablespaces
549Tambouras
550tardis
551Taveira
552Tegeder
553tempdir
554tgisconstraint
555Thauvin
556timesync
557tmp
558tnm
559Tolley
560totalwastedbytes
561totalwastedbytes
562tup
563undef
564unlinked
565upd
566uptime
567USERNAME
568usernames
569USERWHERECLAUSE
570usr
571utf
572valtype
573Villemain
574Vitkovsky
575Vondendriesch
576Waisbrot
577Waisbrot
578wal
579WAL
580watson
581Webber
582Westwood
583wget
584wiki
585Wilke
586wilkins
587xact
588xlog
589Yamada
590Yochum
591Zwerschke
592