File Coverage

blib/lib/Mail/Box/Test.pm
Criterion Covered Total %
statement 115 145 79.3
branch 31 60 51.6
condition 0 6 0.0
subroutine 18 21 85.7
pod 0 9 0.0
total 164 241 68.0


line stmt bran cond sub pod time code
1             # This code is part of Perl distribution Mail-Box version 4.01.
2             # The POD got stripped from this file by OODoc version 3.05.
3             # For contributors see file ChangeLog.
4              
5             # This software is copyright (c) 2001-2025 by Mark Overmeer.
6              
7             # This is free software; you can redistribute it and/or modify it under
8             # the same terms as the Perl 5 programming language system itself.
9             # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later
10              
11             # This code is part of distribution Mail-Message. Meta-POD processed with
12             # OODoc into POD and HTML manual-pages. See README.md
13             # Copyright Mark Overmeer. Licensed under the same terms as Perl itself.
14              
15             package Mail::Box::Test;{
16             our $VERSION = '4.01';
17             }
18              
19 42     42   428444 use parent 'Exporter';
  42         13944  
  42         270  
20              
21 42     42   3223 use strict;
  42         191  
  42         5665  
22 42     42   258 use warnings;
  42         82  
  42         2487  
23              
24 42     42   27254 use Log::Report 'mail-box', import => [ qw// ];
  42         5586334  
  42         248  
25              
26 42     42   33181 use File::Copy qw/copy/;
  42         274097  
  42         5064  
27 42     42   398 use List::Util qw/first/;
  42         107  
  42         4668  
28 42     42   21593 use File::Spec::Functions qw/catdir catfile devnull/;;
  42         44206  
  42         4224  
29 42     42   38510 use File::Temp qw/tempdir/;
  42         1038319  
  42         4686  
30 42     42   426 use Cwd qw/getcwd/;
  42         93  
  42         2566  
31 42     42   21517 use Sys::Hostname qw/hostname/;
  42         62568  
  42         3211  
32 42     42   30664 use Test::More;
  42         4807591  
  42         493  
33              
34              
35             our @EXPORT = qw/
36             clean_dir copy_dir
37             unpack_mbox2mh unpack_mbox2maildir
38             compare_lists listdir
39             compare_message_prints reproducable_text
40             compare_thread_dumps
41              
42             $folderdir
43             $workdir
44             $src $unixsrc $winsrc
45             $fn $unixfn $winfn
46             $cpy $cpyfn
47             $raw_html_data
48             $crlf_platform $windows
49             /;
50              
51             our ($logfile, $folderdir);
52             our ($src, $unixsrc, $winsrc);
53             our ($fn, $unixfn, $winfn);
54             our ($cpy, $cpyfn);
55             our ($crlf_platform, $windows);
56             our $workdir;
57              
58             BEGIN {
59 42     42   30490 $windows = $^O =~ m/mswin32/i;
60 42         135 $crlf_platform = $windows;
61              
62 42         326 $folderdir = catdir 't','folders';
63 42         326 $workdir = tempdir(CLEANUP => 1);
64              
65 42         42086 $logfile = catfile getcwd(), 'run-log';
66 42         553 $unixfn = 'mbox.src';
67 42         201 $winfn = 'mbox.win';
68 42         127 $cpyfn = 'mbox.cpy';
69              
70 42         302 $unixsrc = catfile $folderdir, $unixfn;
71 42         345 $winsrc = catfile $folderdir, $winfn;
72 42         283 $cpy = catfile $workdir, $cpyfn;
73              
74 42 50       328 ($src, $fn) = $windows ? ($winsrc, $winfn) : ($unixsrc, $unixfn);
75              
76             # ensure to test the Perl Parser not the C-Parser (separate distribution)
77 42         27528 require Mail::Box::Parser::Perl;
78 42         1106525 Mail::Box::Parser->defaultParserType('Mail::Box::Parser::Perl');
79             }
80              
81             #
82             # CLEAN_DIR
83             # Clean a directory structure, typically created by unpack_mbox()
84             #
85              
86             sub clean_dir($);
87             sub clean_dir($)
88 11     11 0 225022 { my $dir = shift;
89 11 50       1325 opendir my $dh, $dir or return;
90              
91 0   0     0 my @items = map m/(.*)/ && "$dir/$1", # untainted
92             grep !/^\.\.?$/, readdir $dh;
93              
94 0         0 foreach (@items)
95 0 0       0 { if(-d) { clean_dir $_ }
  0         0  
96 0         0 else { unlink $_ }
97             }
98              
99 0         0 closedir $dh;
100 0         0 rmdir $dir;
101             }
102              
103             #
104             # COPY_DIR FROM, TO
105             # Copy directory to other place (not recursively), cleaning the
106             # destination first.
107             #
108              
109             sub copy_dir($$)
110 0     0 0 0 { my ($orig, $dest) = @_;
111              
112 0         0 clean_dir $dest;
113              
114 0 0       0 mkdir $dest
115             or die "Cannot create copy destination $dest: $!\n";
116              
117 0 0       0 opendir my $dh, $orig
118             or die "Cannot open directory $orig: $!\n";
119              
120 0 0 0     0 foreach my $name (map { !m/^\.\.?$/ && m/(.*)/ ? $1 : () } readdir $dh)
  0         0  
121 0         0 { my $from = catfile($orig, $name);
122 0 0       0 next if -d $from;
123              
124 0         0 my $to = catfile($dest, $name);
125 0 0       0 copy($from, $to) or die "Couldn't copy $from,$to: $!\n";
126             }
127              
128 0         0 close $dh;
129             }
130              
131             # UNPACK_MBOX2MH
132             # Unpack an mbox-file into an MH-directory.
133             # This skips message-nr 13 for testing purposes.
134             # Blanks before "From" are removed.
135              
136             sub unpack_mbox2mh($$)
137 6     6 0 1344526 { my ($file, $dir) = @_;
138              
139 6         44 clean_dir $dir;
140 6         934 mkdir $dir, 0700;
141              
142 6         29 my $count = 1;
143 6         14 my $blank;
144              
145 6 50       374 open my $fh, '<:raw', $file or die;
146 6         315 open my $out, '>:raw', devnull;
147              
148 6         19 local $_;
149 6         313 while(<$fh>)
150 20088 100       122702 { if( /^From / )
151 270         1026 { $out->close;
152 270         16007 undef $blank;
153 270 50       54613 open $out, '>', "$dir/".$count++ or die;
154 270 100       1168 $count++ if $count==13; # skip 13 for test
155 270         1772 next; # from line not included in file.
156             }
157              
158 19818 100       43012 $out->print($blank) if defined $blank;
159              
160 19818 100       48869 if( m/^\015?\012$/ )
161 2400         9703 { $blank = $_;
162 2400         7164 next;
163             }
164              
165 17418         21502 undef $blank;
166 17418         29961 $out->print($_);
167             }
168 6         48 $out->close;
169 6         301 $fh->close;
170             }
171              
172             # UNPACK_MBOX2MAILDIR
173             # Unpack an mbox-file into an Maildir-directory.
174              
175             our @maildir_names =
176             ( '8000000.localhost.23:2,',
177             '90000000.localhost.213:2,',
178             '110000000.localhost.12:2,',
179             '110000001.l.42:2,',
180             '110000002.l.42:2,',
181             '110000002.l.43:2,',
182             '110000004.l.43:2,',
183             '110000005.l.43:2,',
184             '110000006.l.43:2,',
185             '110000007.l.43:2,D',
186             '110000008.l.43:2,DF',
187             '110000009.l.43:2,DFR',
188             '110000010.l.43:2,DFRS',
189             '110000011.l.43:2,DFRST',
190             '110000012.l.43:2,F',
191             '110000013.l.43:2,FR',
192             '110000014.l.43:2,FRS',
193             '110000015.l.43:2,FRST',
194             '110000016.l.43:2,DR',
195             '110000017.l.43:2,DRS',
196             '110000018.l.43:2,DRST',
197             '110000019.l.43:2,FS',
198             '110000020.l.43:2,FST',
199             '110000021.l.43:2,R',
200             '110000022.l.43:2,RS',
201             '110000023.l.43:2,RST',
202             '110000024.l.43:2,S',
203             '110000025.l.43:2,ST',
204             '110000026.l.43:2,T',
205             '110000027.l.43:2,',
206             '110000028.l.43:2,',
207             '110000029.l.43:2,',
208             '110000030.l.43:2,',
209             '110000031.l.43:2,',
210             '110000032.l.43:2,',
211             '110000033.l.43:2,',
212             '110000034.l.43:2,',
213             '110000035.l.43:2,',
214             '110000036.l.43:2,',
215             '110000037.l.43:2,',
216             '110000038.l.43',
217             '110000039.l.43',
218             '110000040.l.43',
219             '110000041.l.43',
220             '110000042.l.43',
221             );
222              
223             sub unpack_mbox2maildir($$)
224 4     4 0 1146198 { my ($file, $dir) = @_;
225 4         30 clean_dir $dir;
226              
227 4 50       30 @maildir_names==45 or die;
228 4 50       765 mkdir $dir or die;
229 4 50       705 mkdir catfile($dir, 'cur') or die;
230 4 50       541 mkdir catfile($dir, 'new') or die;
231 4 50       6002 mkdir catfile($dir, 'tmp') or die;
232              
233 4 50       295 open my $fh, '<:raw', $file or die;
234 4         171 open my $out, '>:raw', devnull;
235              
236 4         15 my $msgnr = 0;
237 4         11 my $last_empty = 0;
238 4         9 my $blank;
239              
240 4         11 local $_;
241 4         228 while(<$fh>)
242 13392 100       76655 { if( m/^From / )
243 180         726 { $out->close;
244 180         10136 undef $blank;
245 180         379 my $now = time;
246 180         646 my $hostname = hostname;
247              
248 180 100       2633 my $msgfile = catfile $dir, ($msgnr > 40 ? 'new' : 'cur'), $maildir_names[$msgnr++];
249              
250 180 50       32020 open $out, ">:raw", $msgfile
251             or die "Create $msgfile: $!\n";
252              
253 180         1669 next; # from line not included in file.
254             }
255              
256 13212 100       22627 $out->print($blank) if defined $blank;
257              
258 13212 100       34892 if( m/^\015?\012$/ )
259 1600         2299 { $blank = $_;
260 1600         4931 next;
261             }
262              
263 11612         13643 undef $blank;
264 11612         19261 $out->print($_);
265             }
266              
267 4         34 $out->close;
268 4         265 $fh->close;
269             }
270              
271             #
272             # Compare two lists.
273             #
274              
275             sub compare_lists($$)
276 16     16 0 609 { my ($first, $second) = @_;
277             #warn "[@$first]==[@$second]\n";
278 16 50       37 return 0 unless @$first == @$second;
279 16         42 for(my $i=0; $i<@$first; $i++)
280 193 50       355 { return 0 unless $first->[$i] eq $second->[$i];
281             }
282 16         88 1;
283             }
284              
285             #
286             # Compare the text of two messages, rather strict.
287             # On CRLF platforms, the Content-Length may be different.
288             #
289              
290             sub compare_message_prints($$$)
291 0     0 0 0 { my ($first, $second, $label) = @_;
292              
293 0 0       0 if($crlf_platform)
294 0         0 { s/Content-Length: \d+/Content-Length: /g for $first, $second;
295             }
296              
297 0         0 is($first, $second, $label);
298             }
299              
300             #
301             # Strip message text down the things which are the same on all
302             # platforms and all situations.
303             #
304              
305             sub reproducable_text($)
306 0     0 0 0 { my $text = shift;
307 0         0 my @lines = split /^/m, $text;
308 0         0 foreach (@lines)
309 0         0 { s/((?:references|message-id|date|content-length)\: ).*/$1/i;
310 0         0 s/boundary-\d+/boundary-/g;
311             }
312 0         0 join '', @lines;
313             }
314              
315             #
316             # Compare two outputs of thread details.
317             # On CRLF platforms, the reported sizes are ignored.
318             #
319              
320             sub compare_thread_dumps($$$)
321 6     6 0 28 { my ($first, $second, $label) = @_;
322              
323 6 50       28 if($crlf_platform)
324 0         0 { $first =~ s/^..../ /gm;
325 0         0 $second =~ s/^..../ /gm;
326             }
327              
328 6         37 is($first, $second, $label);
329             }
330              
331             #
332             # List directory
333             # This removes '.' and '..'
334             #
335              
336             sub listdir($)
337 3     3 0 19 { my $dir = shift;
338 3 50       172 opendir my $list, $dir or return ();
339 3         250 my @entities = grep !/^\.\.?$/, readdir $list;
340 3         45 closedir $list;
341 3         58 @entities;
342             }
343              
344             #
345             # A piece of HTML text which is used in some tests.
346             #
347              
348             our $raw_html_data = <<'TEXT';
349            
350            
351             My home page
352            
353            
354              
355            

Life according to Brian

356              
357             This is normal text, but not in a paragraph.

New paragraph

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

Silly subsection at once

364            

and another chapter

365            

again a section

366            

Normal paragraph, which contains an

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