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-2019 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   20845 use vars '$VERSION';
  42         265  
  42         3003  
11             $VERSION = '3.008';
12              
13 42     42   231 use base 'Exporter';
  42         55  
  42         4368  
14              
15 42     42   227 use strict;
  42         60  
  42         674  
16 42     42   161 use warnings;
  42         72  
  42         1508  
17              
18 42     42   18926 use File::Copy 'copy';
  42         196772  
  42         3178  
19 42     42   272 use List::Util 'first';
  42         73  
  42         4750  
20 42     42   17686 use IO::File; # to overrule open()
  42         350931  
  42         7202  
21 42     42   1724 use File::Spec;
  42         79  
  42         4214  
22 42     42   33251 use File::Temp 'tempdir';
  42         443117  
  42         2474  
23 42     42   272 use Cwd qw(getcwd);
  42         73  
  42         1527  
24 42     42   26605 use Sys::Hostname qw(hostname);
  42         37475  
  42         1961  
25 42     42   27735 use Test::More;
  42         2295794  
  42         350  
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   19966 $windows = $^O =~ m/mswin32/i;
53 42         100 $crlf_platform = $windows;
54              
55 42         522 $folderdir = File::Spec->catdir('t','folders');
56 42         267 $workdir = tempdir(CLEANUP => 1);
57              
58              
59 42         48904 $logfile = File::Spec->catfile(getcwd(), 'run-log');
60 42         138 $unixfn = 'mbox.src';
61 42         99 $winfn = 'mbox.win';
62 42         76 $cpyfn = 'mbox.cpy';
63              
64 42         268 $unixsrc = File::Spec->catfile($folderdir, $unixfn);
65 42         286 $winsrc = File::Spec->catfile($folderdir, $winfn);
66 42         320 $cpy = File::Spec->catfile($workdir, $cpyfn);
67              
68 42 50       211 ($src, $fn) = $windows ? ($winsrc, $winfn) : ($unixsrc, $unixfn);
69              
70             # ensure to test the Perl Parser not the C-Parser (separate distribution)
71 42         19936 require Mail::Box::Parser::Perl;
72 42         762506 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 105 { my $dir = shift;
83 11         46 local *DIR;
84 11 50       403 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 449 { my ($file, $dir) = @_;
132 6         26 clean_dir($dir);
133              
134 6         389 mkdir $dir, 0700;
135 6         21 my $count = 1;
136 6         10 my $blank;
137              
138 6 50       224 open FILE, $file or die;
139 6         241 open OUT, '>', File::Spec->devnull;
140              
141 6         143 while()
142 20088 100       26788 { if( /^From / )
143 270         5698 { close OUT;
144 270         636 undef $blank;
145 270 50       10863 open OUT, ">$dir/".$count++ or die;
146 270 100       902 $count++ if $count==13; # skip 13 for test
147 270         1040 next; # from line not included in file.
148             }
149              
150 19818 100       25049 print OUT $blank
151             if defined $blank;
152              
153 19818 100       27351 if( m/^\015?\012$/ )
154 2400         2769 { $blank = $_;
155 2400         4707 next;
156             }
157              
158 17418         16579 undef $blank;
159 17418         28222 print OUT;
160             }
161              
162 6         134 close OUT;
163 6         77 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 358 { my ($file, $dir) = @_;
219 4         17 clean_dir($dir);
220              
221 4 50       18 die unless @maildir_names==45;
222              
223 4 50       292 mkdir $dir or die;
224 4 50       232 mkdir File::Spec->catfile($dir, 'cur') or die;
225 4 50       172 mkdir File::Spec->catfile($dir, 'new') or die;
226 4 50       165 mkdir File::Spec->catfile($dir, 'tmp') or die;
227 4         17 my $msgnr = 0;
228              
229 4 50       129 open FILE, $file or die;
230 4         149 open OUT, '>', File::Spec->devnull;
231              
232 4         13 my $last_empty = 0;
233 4         7 my $blank;
234              
235 4         83 while()
236 13392 100       18137 { if( m/^From / )
237 180         3987 { close OUT;
238 180         426 undef $blank;
239 180         255 my $now = time;
240 180         549 my $hostname = hostname;
241              
242 180 100       2170 my $msgfile = File::Spec->catfile($dir
243             , ($msgnr > 40 ? 'new' : 'cur')
244             , $maildir_names[$msgnr++]
245             );
246              
247 180 50       7661 open OUT, ">", $msgfile or die "Create $msgfile: $!\n";
248 180         1037 next; # from line not included in file.
249             }
250              
251 13212 100       16823 print OUT $blank
252             if defined $blank;
253              
254 13212 100       18673 if( m/^\015?\012$/ )
255 1600         1825 { $blank = $_;
256 1600         3167 next;
257             }
258              
259 11612         11007 undef $blank;
260 11612         19113 print OUT;
261             }
262              
263 4         86 close OUT;
264 4         46 close FILE;
265             }
266              
267             #
268             # Compare two lists.
269             #
270              
271             sub compare_lists($$)
272 16     16 0 638 { my ($first, $second) = @_;
273             #warn "[@$first]==[@$second]\n";
274 16 50       40 return 0 unless @$first == @$second;
275 16         44 for(my $i=0; $i<@$first; $i++)
276 193 50       366 { return 0 unless $first->[$i] eq $second->[$i];
277             }
278 16         72 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 18 { my ($first, $second, $label) = @_;
319              
320 6 50       16 if($crlf_platform)
321 0         0 { $first =~ s/^..../ /gm;
322 0         0 $second =~ s/^..../ /gm;
323             }
324              
325 6         20 is($first, $second, $label);
326             }
327              
328             #
329             # List directory
330             # This removes '.' and '..'
331             #
332              
333             sub listdir($)
334 3     3 0 138 { my $dir = shift;
335 3 50       94 opendir LISTDIR, $dir or return ();
336 3         178 my @entities = grep !/^\.\.?$/, readdir LISTDIR;
337 3         50 closedir LISTDIR;
338 3         61 @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;