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-2020 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.02.
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   24389 use vars '$VERSION';
  42         316  
  42         3154  
11             $VERSION = '3.009';
12              
13 42     42   283 use base 'Exporter';
  42         80  
  42         5379  
14              
15 42     42   287 use strict;
  42         77  
  42         878  
16 42     42   203 use warnings;
  42         82  
  42         1560  
17              
18 42     42   22036 use File::Copy 'copy';
  42         201041  
  42         3669  
19 42     42   329 use List::Util 'first';
  42         86  
  42         5513  
20 42     42   20837 use IO::File; # to overrule open()
  42         402231  
  42         8564  
21 42     42   2226 use File::Spec;
  42         88  
  42         4811  
22 42     42   41104 use File::Temp 'tempdir';
  42         510431  
  42         2741  
23 42     42   325 use Cwd qw(getcwd);
  42         92  
  42         1811  
24 42     42   18884 use Sys::Hostname qw(hostname);
  42         43947  
  42         2457  
25 42     42   26971 use Test::More;
  42         2716352  
  42         426  
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   24980 $windows = $^O =~ m/mswin32/i;
53 42         128 $crlf_platform = $windows;
54              
55 42         656 $folderdir = File::Spec->catdir('t','folders');
56 42         324 $workdir = tempdir(CLEANUP => 1);
57              
58              
59 42         32798 $logfile = File::Spec->catfile(getcwd(), 'run-log');
60 42         181 $unixfn = 'mbox.src';
61 42         100 $winfn = 'mbox.win';
62 42         98 $cpyfn = 'mbox.cpy';
63              
64 42         323 $unixsrc = File::Spec->catfile($folderdir, $unixfn);
65 42         355 $winsrc = File::Spec->catfile($folderdir, $winfn);
66 42         343 $cpy = File::Spec->catfile($workdir, $cpyfn);
67              
68 42 50       248 ($src, $fn) = $windows ? ($winsrc, $winfn) : ($unixsrc, $unixfn);
69              
70             # ensure to test the Perl Parser not the C-Parser (separate distribution)
71 42         24490 require Mail::Box::Parser::Perl;
72 42         905458 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 137 { my $dir = shift;
83 11         44 local *DIR;
84 11 50       536 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 544 { my ($file, $dir) = @_;
132 6         32 clean_dir($dir);
133              
134 6         564 mkdir $dir, 0700;
135 6         30 my $count = 1;
136 6         14 my $blank;
137              
138 6 50       237 open FILE, $file or die;
139 6         307 open OUT, '>', File::Spec->devnull;
140              
141 6         175 while()
142 20088 100       32500 { if( /^From / )
143 270         7499 { close OUT;
144 270         905 undef $blank;
145 270 50       14094 open OUT, ">$dir/".$count++ or die;
146 270 100       1188 $count++ if $count==13; # skip 13 for test
147 270         1389 next; # from line not included in file.
148             }
149              
150 19818 100       30507 print OUT $blank
151             if defined $blank;
152              
153 19818 100       34221 if( m/^\015?\012$/ )
154 2400         3366 { $blank = $_;
155 2400         5842 next;
156             }
157              
158 17418         20820 undef $blank;
159 17418         34565 print OUT;
160             }
161              
162 6         171 close OUT;
163 6         93 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 432 { my ($file, $dir) = @_;
219 4         24 clean_dir($dir);
220              
221 4 50       26 die unless @maildir_names==45;
222              
223 4 50       401 mkdir $dir or die;
224 4 50       274 mkdir File::Spec->catfile($dir, 'cur') or die;
225 4 50       244 mkdir File::Spec->catfile($dir, 'new') or die;
226 4 50       221 mkdir File::Spec->catfile($dir, 'tmp') or die;
227 4         19 my $msgnr = 0;
228              
229 4 50       169 open FILE, $file or die;
230 4         196 open OUT, '>', File::Spec->devnull;
231              
232 4         18 my $last_empty = 0;
233 4         7 my $blank;
234              
235 4         115 while()
236 13392 100       22090 { if( m/^From / )
237 180         4939 { close OUT;
238 180         570 undef $blank;
239 180         341 my $now = time;
240 180         647 my $hostname = hostname;
241              
242 180 100       2851 my $msgfile = File::Spec->catfile($dir
243             , ($msgnr > 40 ? 'new' : 'cur')
244             , $maildir_names[$msgnr++]
245             );
246              
247 180 50       9805 open OUT, ">", $msgfile or die "Create $msgfile: $!\n";
248 180         1326 next; # from line not included in file.
249             }
250              
251 13212 100       20187 print OUT $blank
252             if defined $blank;
253              
254 13212 100       22921 if( m/^\015?\012$/ )
255 1600         2286 { $blank = $_;
256 1600         4212 next;
257             }
258              
259 11612         13512 undef $blank;
260 11612         23133 print OUT;
261             }
262              
263 4         117 close OUT;
264 4         67 close FILE;
265             }
266              
267             #
268             # Compare two lists.
269             #
270              
271             sub compare_lists($$)
272 16     16 0 841 { my ($first, $second) = @_;
273             #warn "[@$first]==[@$second]\n";
274 16 50       45 return 0 unless @$first == @$second;
275 16         57 for(my $i=0; $i<@$first; $i++)
276 193 50       409 { return 0 unless $first->[$i] eq $second->[$i];
277             }
278 16         83 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 22 { my ($first, $second, $label) = @_;
319              
320 6 50       20 if($crlf_platform)
321 0         0 { $first =~ s/^..../ /gm;
322 0         0 $second =~ s/^..../ /gm;
323             }
324              
325 6         25 is($first, $second, $label);
326             }
327              
328             #
329             # List directory
330             # This removes '.' and '..'
331             #
332              
333             sub listdir($)
334 3     3 0 18 { my $dir = shift;
335 3 50       114 opendir LISTDIR, $dir or return ();
336 3         231 my @entities = grep !/^\.\.?$/, readdir LISTDIR;
337 3         65 closedir LISTDIR;
338 3         60 @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;