File Coverage

blib/lib/Mail/Box/Test.pm
Criterion Covered Total %
statement 117 149 78.5
branch 31 62 50.0
condition 0 3 0.0
subroutine 19 22 86.3
pod 0 9 0.0
total 167 245 68.1


line stmt bran cond sub pod time code
1             # Copyrights 2001-2023 by [Mark Overmeer].
2             # For other contributors see ChangeLog.
3             # See the manual pages for details on the licensing terms.
4             # Pod stripped from pm file by OODoc 2.03.
5             # This code is part of distribution Mail-Box. Meta-POD processed with
6             # OODoc into POD and HTML manual-pages. See README.md
7             # Copyright Mark Overmeer. Licensed under the same terms as Perl itself.
8              
9             package Mail::Box::Test;
10 42     42   24930 use vars '$VERSION';
  42         333  
  42         3312  
11             $VERSION = '3.010';
12              
13 42     42   295 use base 'Exporter';
  42         79  
  42         5875  
14              
15 42     42   324 use strict;
  42         93  
  42         1159  
16 42     42   237 use warnings;
  42         152  
  42         1544  
17              
18 42     42   22037 use File::Copy 'copy';
  42         203660  
  42         3780  
19 42     42   324 use List::Util 'first';
  42         106  
  42         5613  
20 42     42   20112 use IO::File; # to overrule open()
  42         407073  
  42         6227  
21 42     42   2029 use File::Spec;
  42         1605  
  42         7433  
22 42     42   33359 use File::Temp 'tempdir';
  42         491898  
  42         2747  
23 42     42   323 use Cwd qw(getcwd);
  42         81  
  42         1898  
24 42     42   19019 use Sys::Hostname qw(hostname);
  42         43145  
  42         2402  
25 42     42   27079 use Test::More;
  42         2708261  
  42         389  
26              
27              
28             our @EXPORT =
29             qw/clean_dir copy_dir
30             unpack_mbox2mh unpack_mbox2maildir
31             compare_lists listdir
32             compare_message_prints reproducable_text
33             compare_thread_dumps
34              
35             $folderdir
36             $workdir
37             $src $unixsrc $winsrc
38             $fn $unixfn $winfn
39             $cpy $cpyfn
40             $raw_html_data
41             $crlf_platform $windows
42             /;
43              
44             our ($logfile, $folderdir);
45             our ($src, $unixsrc, $winsrc);
46             our ($fn, $unixfn, $winfn);
47             our ($cpy, $cpyfn);
48             our ($crlf_platform, $windows);
49             our $workdir;
50              
51             BEGIN {
52 42     42   25026 $windows = $^O =~ m/mswin32/i;
53 42         163 $crlf_platform = $windows;
54              
55 42         711 $folderdir = File::Spec->catdir('t','folders');
56 42         326 $workdir = tempdir(CLEANUP => 1);
57              
58              
59 42         35311 $logfile = File::Spec->catfile(getcwd(), 'run-log');
60 42         228 $unixfn = 'mbox.src';
61 42         120 $winfn = 'mbox.win';
62 42         125 $cpyfn = 'mbox.cpy';
63              
64 42         286 $unixsrc = File::Spec->catfile($folderdir, $unixfn);
65 42         342 $winsrc = File::Spec->catfile($folderdir, $winfn);
66 42         423 $cpy = File::Spec->catfile($workdir, $cpyfn);
67              
68 42 50       322 ($src, $fn) = $windows ? ($winsrc, $winfn) : ($unixsrc, $unixfn);
69              
70             # ensure to test the Perl Parser not the C-Parser (separate distribution)
71 42         23094 require Mail::Box::Parser::Perl;
72 42         912889 Mail::Box::Parser->defaultParserType( 'Mail::Box::Parser::Perl' );
73             }
74              
75             #
76             # CLEAN_DIR
77             # Clean a directory structure, typically created by unpack_mbox()
78             #
79              
80             sub clean_dir($);
81             sub clean_dir($)
82 11     11 0 166 { my $dir = shift;
83 11         50 local *DIR;
84 11 50       618 opendir DIR, $dir or return;
85              
86 0 0       0 my @items = map { m/(.*)/ && "$dir/$1" } # untainted
  0         0  
87             grep !/^\.\.?$/, readdir DIR;
88 0         0 foreach (@items)
89 0 0       0 { if(-d) { clean_dir $_ }
  0         0  
90 0         0 else { unlink $_ }
91             }
92              
93 0         0 closedir DIR;
94 0         0 rmdir $dir;
95             }
96              
97             #
98             # COPY_DIR FROM, TO
99             # Copy directory to other place (not recursively), cleaning the
100             # destination first.
101             #
102              
103             sub copy_dir($$)
104 0     0 0 0 { my ($orig, $dest) = @_;
105              
106 0         0 clean_dir($dest);
107              
108 0 0       0 mkdir $dest
109             or die "Cannot create copy destination $dest: $!\n";
110              
111 0 0       0 opendir ORIG, $orig
112             or die "Cannot open directory $orig: $!\n";
113              
114 0 0 0     0 foreach my $name (map { !m/^\.\.?$/ && m/(.*)/ ? $1 : () } readdir ORIG)
  0         0  
115 0         0 { my $from = File::Spec->catfile($orig, $name);
116 0 0       0 next if -d $from;
117              
118 0         0 my $to = File::Spec->catfile($dest, $name);
119 0 0       0 copy($from, $to) or die "Couldn't copy $from,$to: $!\n";
120             }
121              
122 0         0 close ORIG;
123             }
124              
125             # UNPACK_MBOX2MH
126             # Unpack an mbox-file into an MH-directory.
127             # This skips message-nr 13 for testing purposes.
128             # Blanks before "From" are removed.
129              
130             sub unpack_mbox2mh($$)
131 6     6 0 579 { my ($file, $dir) = @_;
132 6         29 clean_dir($dir);
133              
134 6         578 mkdir $dir, 0700;
135 6         34 my $count = 1;
136 6         18 my $blank;
137              
138 6 50       278 open FILE, $file or die;
139 6         386 open OUT, '>', File::Spec->devnull;
140              
141 6         250 while()
142 20088 100       33013 { if( /^From / )
143 270         9005 { close OUT;
144 270         894 undef $blank;
145 270 50       17533 open OUT, ">$dir/".$count++ or die;
146 270 100       1210 $count++ if $count==13; # skip 13 for test
147 270         1444 next; # from line not included in file.
148             }
149              
150 19818 100       30090 print OUT $blank
151             if defined $blank;
152              
153 19818 100       34067 if( m/^\015?\012$/ )
154 2400         3489 { $blank = $_;
155 2400         5987 next;
156             }
157              
158 17418         19889 undef $blank;
159 17418         34407 print OUT;
160             }
161              
162 6         217 close OUT;
163 6         86 close FILE;
164             }
165              
166             # UNPACK_MBOX2MAILDIR
167             # Unpack an mbox-file into an Maildir-directory.
168              
169             our @maildir_names =
170             ( '8000000.localhost.23:2,'
171             , '90000000.localhost.213:2,'
172             , '110000000.localhost.12:2,'
173             , '110000001.l.42:2,'
174             , '110000002.l.42:2,'
175             , '110000002.l.43:2,'
176             , '110000004.l.43:2,'
177             , '110000005.l.43:2,'
178             , '110000006.l.43:2,'
179             , '110000007.l.43:2,D'
180             , '110000008.l.43:2,DF'
181             , '110000009.l.43:2,DFR'
182             , '110000010.l.43:2,DFRS'
183             , '110000011.l.43:2,DFRST'
184             , '110000012.l.43:2,F'
185             , '110000013.l.43:2,FR'
186             , '110000014.l.43:2,FRS'
187             , '110000015.l.43:2,FRST'
188             , '110000016.l.43:2,DR'
189             , '110000017.l.43:2,DRS'
190             , '110000018.l.43:2,DRST'
191             , '110000019.l.43:2,FS'
192             , '110000020.l.43:2,FST'
193             , '110000021.l.43:2,R'
194             , '110000022.l.43:2,RS'
195             , '110000023.l.43:2,RST'
196             , '110000024.l.43:2,S'
197             , '110000025.l.43:2,ST'
198             , '110000026.l.43:2,T'
199             , '110000027.l.43:2,'
200             , '110000028.l.43:2,'
201             , '110000029.l.43:2,'
202             , '110000030.l.43:2,'
203             , '110000031.l.43:2,'
204             , '110000032.l.43:2,'
205             , '110000033.l.43:2,'
206             , '110000034.l.43:2,'
207             , '110000035.l.43:2,'
208             , '110000036.l.43:2,'
209             , '110000037.l.43:2,'
210             , '110000038.l.43'
211             , '110000039.l.43'
212             , '110000040.l.43'
213             , '110000041.l.43'
214             , '110000042.l.43'
215             );
216              
217             sub unpack_mbox2maildir($$)
218 4     4 0 505 { my ($file, $dir) = @_;
219 4         19 clean_dir($dir);
220              
221 4 50       47 die unless @maildir_names==45;
222              
223 4 50       630 mkdir $dir or die;
224 4 50       3730 mkdir File::Spec->catfile($dir, 'cur') or die;
225 4 50       338 mkdir File::Spec->catfile($dir, 'new') or die;
226 4 50       292 mkdir File::Spec->catfile($dir, 'tmp') or die;
227 4         30 my $msgnr = 0;
228              
229 4 50       252 open FILE, $file or die;
230 4         234 open OUT, '>', File::Spec->devnull;
231              
232 4         26 my $last_empty = 0;
233 4         8 my $blank;
234              
235 4         154 while()
236 13392 100       21951 { if( m/^From / )
237 180         5947 { close OUT;
238 180         619 undef $blank;
239 180         338 my $now = time;
240 180         635 my $hostname = hostname;
241              
242 180 100       3060 my $msgfile = File::Spec->catfile($dir
243             , ($msgnr > 40 ? 'new' : 'cur')
244             , $maildir_names[$msgnr++]
245             );
246              
247 180 50       11369 open OUT, ">", $msgfile or die "Create $msgfile: $!\n";
248 180         1517 next; # from line not included in file.
249             }
250              
251 13212 100       20285 print OUT $blank
252             if defined $blank;
253              
254 13212 100       22892 if( m/^\015?\012$/ )
255 1600         2244 { $blank = $_;
256 1600         3961 next;
257             }
258              
259 11612         13616 undef $blank;
260 11612         23489 print OUT;
261             }
262              
263 4         140 close OUT;
264 4         69 close FILE;
265             }
266              
267             #
268             # Compare two lists.
269             #
270              
271             sub compare_lists($$)
272 16     16 0 840 { my ($first, $second) = @_;
273             #warn "[@$first]==[@$second]\n";
274 16 50       53 return 0 unless @$first == @$second;
275 16         51 for(my $i=0; $i<@$first; $i++)
276 193 50       440 { return 0 unless $first->[$i] eq $second->[$i];
277             }
278 16         110 1;
279             }
280              
281             #
282             # Compare the text of two messages, rather strict.
283             # On CRLF platforms, the Content-Length may be different.
284             #
285              
286             sub compare_message_prints($$$)
287 0     0 0 0 { my ($first, $second, $label) = @_;
288              
289 0 0       0 if($crlf_platform)
290 0         0 { $first =~ s/Content-Length: (\d+)/Content-Length: /g;
291 0         0 $second =~ s/Content-Length: (\d+)/Content-Length: /g;
292             }
293              
294 0         0 is($first, $second, $label);
295             }
296              
297             #
298             # Strip message text down the things which are the same on all
299             # platforms and all situations.
300             #
301              
302             sub reproducable_text($)
303 0     0 0 0 { my $text = shift;
304 0         0 my @lines = split /^/m, $text;
305 0         0 foreach (@lines)
306 0         0 { s/((?:references|message-id|date|content-length)\: ).*/$1/i;
307 0         0 s/boundary-\d+/boundary-/g;
308             }
309 0         0 join '', @lines;
310             }
311              
312             #
313             # Compare two outputs of thread details.
314             # On CRLF platforms, the reported sizes are ignored.
315             #
316              
317             sub compare_thread_dumps($$$)
318 6     6 0 24 { my ($first, $second, $label) = @_;
319              
320 6 50       21 if($crlf_platform)
321 0         0 { $first =~ s/^..../ /gm;
322 0         0 $second =~ s/^..../ /gm;
323             }
324              
325 6         27 is($first, $second, $label);
326             }
327              
328             #
329             # List directory
330             # This removes '.' and '..'
331             #
332              
333             sub listdir($)
334 3     3 0 16 { my $dir = shift;
335 3 50       118 opendir LISTDIR, $dir or return ();
336 3         280 my @entities = grep !/^\.\.?$/, readdir LISTDIR;
337 3         76 closedir LISTDIR;
338 3         64 @entities;
339             }
340              
341             #
342             # A piece of HTML text which is used in some tests.
343             #
344              
345             our $raw_html_data = <<'TEXT';
346            
347            
348             My home page
349            
350            
351              
352            

Life according to Brian

353              
354             This is normal text, but not in a paragraph.

New paragraph

355             in a bad way.
356              
357             And this is just a continuation. When texts get long, they must be
358             auto-wrapped; and even that is working already.
359              
360            

Silly subsection at once

361            

and another chapter

362            

again a section

363            

Normal paragraph, which contains an

364             SRC=image.gif>, some
365             italics with linebreak
366             and code
367              
368            
 
369             And now for the preformatted stuff
370             it should stay as it was
371             even with strange blanks
372             and indentations
373            
374              
375             And back to normal text...
376            
377            
  • list item 1
  • 378            
    379            
  • list item 1.1
  • 380            
  • list item 1.2
  • 381            
    382            
  • list item 2
  • 383            
    384            
    385            
    386             TEXT
    387              
    388             1;