File Coverage

blib/lib/Test/Mock/Net/FTP.pm
Criterion Covered Total %
statement 289 292 98.9
branch 77 82 93.9
condition 5 6 83.3
subroutine 78 80 97.5
pod 52 52 100.0
total 501 512 97.8


line stmt bran cond sub pod time code
1             package Test::Mock::Net::FTP;
2 18     18   422007 use strict;
  18         47  
  18         598  
3 18     18   146 use warnings;
  18         234  
  18         604  
4              
5 18     18   15380 use File::Copy;
  18         83876  
  18         1643  
6 18     18   3859 use File::Spec::Functions qw( catdir splitdir rootdir catfile curdir rel2abs abs2rel );
  18         2936  
  18         1727  
7 18     18   105 use File::Basename;
  18         35  
  18         1922  
8 18     18   106 use Cwd qw(getcwd);
  18         33  
  18         699  
9 18     18   2040 use Carp;
  18         35  
  18         1375  
10 18     18   100 use File::Path qw(make_path remove_tree);
  18         32  
  18         1013  
11 18     18   18719 use File::Slurp;
  18         347208  
  18         86650  
12              
13             our $VERSION = '0.02';
14              
15             =head1 NAME
16              
17             Test::Mock::Net::FTP - Mock Object for Net::FTP
18              
19             =head1 SYNOPSIS
20              
21             use strict;
22             use warnings;
23              
24             use Test::More;
25             use Test::Mock::Net::FTP;
26              
27             Test::Mock::Net::FTP::mock_prepare(
28             'somehost.example.com' => {
29             'user1'=> {
30             password => 'secret',
31             dir => ['./ftpserver', '/ftproot'],
32             override => {
33             ls => sub {
34             return qw(aaa bbb ccc);
35             },
36             },
37             },
38             }
39             );
40             my $ftp = Test::Mock::Net::FTP->new('somehost.example.com');
41             $ftp->login('user1', 'secret');
42             $ftp->cwd('datadir');
43             $ftp->get('file1');
44             my @files = $ftp->ls();# => ('aaa', 'bbb', 'ccc');
45             $ftp->quit();
46             # or
47             use Test::Mock::Net::FTP qw(intercept);
48             some_method_using_ftp();
49              
50             =head1 DESCRIPTION
51              
52             Test::Mock::Net::FTP is Mock Object for Net::FTP. This module behave like FTP server, but only use local filesystem.(not using socket).
53              
54             =head1 NOTICE
55              
56             =over 4
57              
58             =item
59             This module is implemented all Net::FTP's methods, but some methods are 'do nothing' currently. These methods behavior may be changed in future release.
60              
61             =item
62             This module works in only Unix-like systems(does not work in MS-Windows).
63              
64             =item
65             Some errors are not reproduced in this module.
66              
67             =item
68             If you don't like default implementation of methods in this module, you can use override (or RT to me :-)
69              
70             =back
71              
72             =cut
73              
74             my %mock_server;
75             my $cwd_when_prepared;
76              
77             =head1 METHODS
78              
79             =cut
80              
81             =head2 mock_prepare( %params )
82              
83             prepare FTP server in your local filesystem.
84              
85             =cut
86              
87             sub mock_prepare {
88 184     184 1 205740 my %args = @_;
89 184         1007 %mock_server = %args;
90 184         1311 $cwd_when_prepared = getcwd();
91             }
92              
93             =head2 mock_pwd()
94              
95             mock's current directory
96              
97             =cut
98              
99             sub mock_pwd {
100 55     55 1 621 my ($self) = @_;
101 55         161 return catdir($self->mock_physical_root, $self->_mock_cwd);
102             }
103              
104             =head2 mock_physical_root()
105              
106             mock's physical root directory
107              
108             =cut
109              
110             sub mock_physical_root {
111 81     81 1 2020 my ($self) = @_;
112 81         741 return $self->{mock_physical_root};
113             }
114              
115             =head2 mock_connection_mode()
116              
117             return current connection mode (port or pasv)
118              
119             =cut
120              
121             sub mock_connection_mode {
122 5     5 1 31 my ($self) = @_;
123              
124 5         23 return $self->{mock_connection_mode};
125             }
126              
127             =head2 mock_port_no()
128              
129             return current port no
130              
131             =cut
132              
133             sub mock_port_no {
134 5     5 1 11 my ($self) = @_;
135              
136 5         20 return $self->{mock_port_no};
137             }
138              
139             =head2 mock_transfer_mode()
140              
141             return current transfer mode(ascii or binary)
142              
143             =cut
144              
145             sub mock_transfer_mode {
146 3     3 1 11 my ($self) = @_;
147              
148 3         13 return $self->{mock_transfer_mode};
149             }
150              
151             =head2 mock_command_history()
152              
153             return command history
154              
155             my $ftp = Test::Mock::Net::FTP->new('somehost');
156             $ftp->login('somehost', 'passwd');
157             $ftp->ls('dir1');
158             my @history = $ftp->mock_command_history();
159             # => ( ['login', 'somehost', 'passwd'], ['ls', 'dir1']);
160              
161             =cut
162              
163             sub mock_command_history {
164 43     43 1 165 my ($self) = @_;
165              
166 43         41 return @{ $self->{mock_command_history} };
  43         204  
167             }
168              
169             sub _push_mock_command_history {
170 556     556   1473 my ($self, $method_name, @args) = @_;
171 556         690 shift @args; #discard $self;
172 556         630 push @{ $self->{mock_command_history} }, [$method_name, @args];
  556         2162  
173             }
174              
175             =head2 mock_clear_command_history()
176              
177             clear command history
178              
179             =cut
180              
181             sub mock_clear_command_history {
182 83     83 1 287 my ($self) = @_;
183              
184 83         317 $self->{mock_command_history} = [];
185             }
186              
187              
188             =head2 new( $host, %options )
189              
190             create new instance
191              
192             =cut
193              
194             sub new {
195 250     250 1 152318 my ($class, $host, %opts ) = @_;
196 250 100       787 return if ( !exists $mock_server{$host} );
197              
198 249         576 my ($connection_mode, $port_no) = _connection_mode_and_port_no(%opts);
199              
200 249         2047 my $self = {
201             mock_host => $host,
202             mock_physical_root => '',
203             mock_server_root => '',
204             mock_transfer_mode => 'ascii',
205             mock_connection_mode => $connection_mode,
206             mock_port_no => $port_no,
207             message => '',
208             mock_command_history => [],
209             };
210 249         1240 bless $self, $class;
211             }
212              
213             sub _connection_mode_and_port_no {
214 249     249   370 my (%opts) = @_;
215 249 100 66     1483 my $connection_mode = ((!defined $opts{Passive} && !defined $opts{Port} ) || !!$opts{Passive}) ? 'pasv' : 'port';
216 249 100       551 my $port_no = $connection_mode eq 'pasv' ? ''
    100          
217             : defined $opts{Port} ? $opts{Port}
218             : '20';
219 249         619 return ($connection_mode, $port_no);
220             }
221              
222             =head2 login( $user, $password )
223              
224             login mock FTP server. this method IS NOT allowed to be overridden.
225              
226             =cut
227              
228             sub login {
229 250     250 1 2073 my ($self, $user, $pass) = @_;
230 250         674 $self->_push_mock_command_history('login', @_);
231              
232 250 100       616 if ( $self->_mock_login_auth( $user, $pass) ) {# auth success
233 249         1439 my $cwd = getcwd();
234 249         4332 chdir $cwd_when_prepared;# chdir for absolute path
235 249         572 my $mock_server_for_user = $mock_server{$self->{mock_host}}->{$user};
236 249         394 my $dir = $mock_server_for_user->{dir};
237 249 100       1225 $self->{mock_physical_root} = rel2abs($dir->[0]) if defined $dir->[0];
238 249         11901 $self->{mock_server_root} = $dir->[1];
239 249         500 $self->{mock_cwd} = rootdir();
240 249         524 $self->{mock_override} = $mock_server_for_user->{override};
241 249         3183 chdir $cwd;
242 249         665 return 1;
243             }
244 1         2 $self->{message} = 'Login incorrect.';
245 1         4 return;
246             }
247              
248             sub _mock_login_auth {
249 250     250   462 my ($self, $user, $pass) = @_;
250              
251 250         560 my $server_user = $mock_server{$self->{mock_host}}->{$user};
252 250 100       598 return if !defined $server_user; #user not found
253              
254 249         351 my $server_password = $server_user->{password};
255 249         860 return $server_password eq $pass;
256             }
257              
258             =head2 authorize( [$auth, [$resp]] )
259              
260             authorize.
261             default implementation is 'do nothing'. this method is allowed to be overridden.
262              
263             =cut
264              
265              
266             =head2 mock_default_authorize( [$auth, [$resp]] )
267              
268             default implementation for authorize. this method sholud be used in overridden method.
269              
270             =cut
271              
272             sub mock_default_authorize {
273 1     1 1 3 my ($self, $auth, $resp) = @_;
274 1         3 return 1;
275             }
276              
277             =head2 site( @args )
278              
279             execute SITE command.
280             default implementation is 'do nothing'. this method is allowed to be overridden.
281              
282             =cut
283              
284              
285             =head2 mock_default_site( @args )
286              
287             default implementation for site. this method sholud be used in overridden method.
288              
289             =cut
290              
291             sub mock_default_site {
292 1     1 1 3 my ($self, @args) = @_;
293 1         3 return 1;
294             }
295              
296             =head2 ascii()
297              
298             enter ascii mode.
299             mock_transfer_mode() returns 'ascii'.
300             this methos is allowed to be overridden.
301              
302             =cut
303              
304              
305             =head2 mock_default_ascii()
306              
307             default implementation for ascii. this method sholud be used in overridden method.
308              
309             =cut
310              
311             sub mock_default_ascii {
312 1     1 1 2 my ($self) = @_;
313 1         3 $self->{mock_transfer_mode} = 'ascii';
314             }
315              
316             =head2 binary()
317              
318             enter binary mode.
319             mock_transfer_mode() returns 'binary'.
320             this methos is allowed to be overridden.
321              
322             =cut
323              
324              
325             =head2 mock_default_binary()
326              
327             default implementation for binary. this method sholud be used in overridden method.
328              
329             =cut
330              
331             sub mock_default_binary {
332 1     1 1 2 my ($self) = @_;
333 1         3 $self->{mock_transfer_mode} = 'binary';
334             }
335              
336             =head2 rename($oldname, $newname)
337              
338             rename remote file.
339             this methos is allowed to be overridden.
340              
341             =cut
342              
343              
344             =head2 mock_default_rename($oldname, $newname)
345              
346             default implementation for rename. this method sholud be used in overridden method.
347              
348             =cut
349              
350             sub mock_default_rename {
351 2     2 1 4 my ($self, $oldname, $newname) = @_;
352 2 100       5 unless( CORE::rename $self->_abs_remote($oldname), $self->_abs_remote($newname) ) {
353 1         10 $self->{message} = sprintf("%s: %s\n", $oldname, $!);
354 1         4 return;
355             }
356             }
357              
358             =head2 delete( $filename )
359              
360             delete remote file.
361             this methos is allowed to be overridden.
362              
363             =cut
364              
365              
366             =head2 mock_default_delete( $filename )
367              
368             default implementation for delete. this method sholud be used in overridden method.
369              
370             =cut
371              
372             sub mock_default_delete {
373 2     2 1 3 my ($self, $filename) = @_;
374              
375 2 100       19 unless( unlink $self->_abs_remote($filename) ) {
376 1         12 $self->{message} = sprintf("%s: %s\n", $filename, $!);
377 1         6 return;
378             }
379             }
380              
381             =head2 cwd( $dir )
382              
383             change (mock) server current directory
384             this methos is allowed to be overridden.
385              
386             =cut
387              
388              
389             =head2 mock_default_cwd( $dir )
390              
391             default implementation for cwd. this method sholud be used in overridden method.
392              
393             =cut
394              
395             sub mock_default_cwd {
396 32     32 1 70 my ($self, $dirs) = @_;
397              
398 32 100       105 if ( !defined $dirs ) {
399 5         14 $self->{mock_cwd} = rootdir();
400 5         16 $dirs = "";
401             }
402              
403 32         148 my $backup_cwd = $self->_mock_cwd;
404 32         136 for my $dir ( splitdir($dirs) ) {
405 37         287 $self->_mock_cwd_each($dir);
406             }
407 32         317 $self->{mock_cwd} =~ s/^$self->{mock_server_root}//;#for absolute path
408 32         116 return $self->_mock_check_pwd($backup_cwd);
409             }
410              
411             =head2 cdup()
412              
413             change (mock) server directory to parent
414             this methos is allowed to be overridden.
415              
416             =cut
417              
418              
419             =head2 mock_default_cdup()
420              
421             default implementation for cdup. this method sholud be used in overridden method.
422              
423             =cut
424              
425             sub mock_default_cdup {
426 4     4 1 7 my ($self) = @_;
427 4         9 my $backup_cwd = $self->_mock_cwd;
428 4         9 $self->{mock_cwd} = dirname($self->_mock_cwd);# to updir
429 4         10 return $self->_mock_check_pwd($backup_cwd);
430             }
431              
432             =head2 pwd()
433              
434             return (mock) server current directory
435             this methos is allowed to be overridden.
436              
437             =cut
438              
439              
440             =head2 mock_default_pwd()
441              
442             default implementation for pwd. this method sholud be used in overridden method.
443              
444             =cut
445              
446             sub mock_default_pwd {
447 11     11 1 33 my ($self) = @_;
448 11         37 return catdir($self->{mock_server_root}, $self->_mock_cwd);
449             }
450              
451             sub _mock_cwd_each {
452 37     37   68 my ($self, $dir) = @_;
453              
454 37 100       106 if ( $dir eq '..' ) {
455 3         17 $self->cdup();
456             }
457             else {
458 34         95 $self->{mock_cwd} = catdir($self->_mock_cwd, $dir);
459             }
460             }
461              
462             # check if mock server directory "phisically" exists.
463             sub _mock_check_pwd {
464 36     36   107 my ($self, $backup_cwd) = @_;
465              
466 36 100       114 if ( ! -d $self->mock_pwd ) {
467 1         5 $self->{mock_cwd} = $backup_cwd;
468 1         4 $self->{message} = 'Failed to change directory.';
469 1         10 return 0;
470             }
471 35         139 return 1;
472             }
473              
474             =head2 restart( $where )
475              
476             restart. currently do_nothing
477             this methos is allowed to be overridden.
478              
479             =cut
480              
481              
482             =head2 mock_default_restart( $where )
483              
484             default implementation for restart. this method sholud be used in overridden method.
485              
486             =cut
487              
488             sub mock_default_restart {
489 1     1 1 2 my ($self, $where) = @_;
490 1         4 return 1;
491             }
492              
493             =head2 rmdir( $dirname, $recursive_bool )
494              
495             rmdir to remove (mock) server. when $recursive_bool is true, dir is recursively removed.
496             this methos is allowed to be overridden.
497              
498             =cut
499              
500              
501             =head2 mock_default_rmdir( $dirname, $recursive_bool )
502              
503             default implementation for rmdir. this method sholud be used in overridden method.
504              
505             =cut
506              
507             sub mock_default_rmdir {
508 4     4 1 6 my ($self, $dirname, $recursive_bool) = @_;
509 4 100       11 if ( !!$recursive_bool ) {
510 2 100       7 unless( remove_tree( $self->_abs_remote($dirname) ) ) {
511 1         7 $self->{message} = sprintf("%s: %s", $dirname, $!);
512 1         5 return;
513             }
514             }
515             else {
516 2 100       7 unless( CORE::rmdir $self->_abs_remote($dirname) ) {
517 1         11 $self->{message} = sprintf("%s: %s", $dirname, $!);
518 1         5 return;
519             }
520             }
521             }
522              
523             =head2 mkdir( $dirname, $recursive_bool )
524              
525             mkdir to remove (mock) server. when $recursive_bool is true, dir is recursively create.
526             this methos is allowed to be overridden.
527              
528             =cut
529              
530              
531             =head2 mock_default_mkdir( $dirname, $recursive_bool )
532              
533             default implementation for mkdir. this method sholud be used in overridden method.
534              
535             =cut
536              
537             sub mock_default_mkdir {
538 5     5 1 11 my ($self, $dirname, $recursive_bool) = @_;
539 5 100       10 if ( !!$recursive_bool ) {
540 2 100       8 unless( make_path( $self->_abs_remote($dirname) ) ) {
541 1         6 $self->{message} = sprintf("%s: %s", $dirname, $!);
542 1         5 return;
543             }
544             }
545             else {
546 3 100       9 unless( CORE::mkdir $self->_abs_remote($dirname) ) {
547 1         8 $self->{message} = sprintf("%s: %s", $dirname, $!);
548 1         5 return;
549             }
550             }
551             }
552              
553             =head2 alloc( $size, [$record_size] )
554              
555             alloc.
556             default implementation is 'do nothing'. this method is allowed to be overridden.
557              
558             =cut
559              
560              
561             =head2 mock_default_alloc( $size, [$record_size] )
562              
563             default implementation for alloc. this method sholud be used in overridden method.
564              
565             =cut
566              
567             sub mock_default_alloc {
568 1     1 1 2 my ($self, $size, $record_size) = @_;
569 1         4 return 1;
570             }
571              
572             =head2 ls( [$dir] )
573              
574             list file(s) in server directory.
575             this methos is allowed to be overridden.
576              
577             =cut
578              
579              
580             =head2 mock_default_ls( [$dir] )
581              
582             default implementation for ls. this method sholud be used in overridden method.
583              
584             =cut
585              
586             sub mock_default_ls {
587 4     4 1 7 my ($self, $dir) = @_;
588              
589 4         12 my @ls = $self->_list_files($dir);
590 4 100       12 my @result = (defined $dir)? map{ catfile($dir, $_) } @ls : @ls;
  6         28  
591              
592 4 100       19 return @result if ( wantarray() );
593 1         3 return \@result;
594             }
595              
596             sub _list_files {
597 4     4   5 my ($self, $dir) = @_;
598 4         10 my $target_dir = $self->_relative_remote($dir);
599 4 50       169 opendir my $dh, $target_dir or die $!;
600 4         75 my @files = sort grep { $_ !~ /^\.?\.$/ } readdir($dh);
  16         62  
601 4         55 closedir $dh;
602 4         19 return @files;
603             }
604              
605             =head2 dir( [$dir] )
606              
607             list file(s) with detail information(ex. filesize) in server directory.
608             this methos is allowed to be overridden.
609              
610             =cut
611              
612              
613             =head2 mock_default_dir( [$dir] )
614              
615             default implementation for dir. this method sholud be used in overridden method.
616              
617             =cut
618              
619             sub mock_default_dir {
620 4     4 1 11 my ($self, $dir) = @_;
621 4         44 my $target_dir = $self->_relative_remote($dir);
622 4         46 local $ENV{LC_ALL} = "C";
623 4         45688 my @dir = split(/\n/, `ls -l $target_dir`);
624              
625 4 100       217 return @dir if ( wantarray() );
626 1         124 return \@dir;
627             }
628              
629             =head2 get( $remote_file, [$local_file] )
630              
631             get file from mock FTP server
632             this methos is allowed to be overridden.
633              
634             =cut
635              
636              
637             =head2 mock_default_get( $remote_file, [$local_file] )
638              
639             default implementation for get. this method sholud be used in overridden method.
640              
641             =cut
642              
643             sub mock_default_get {
644 5     5 1 8 my($self, $remote_file, $local_file) = @_;
645 5 100       155 $local_file = basename($remote_file) if ( !defined $local_file );
646 5 100       20 unless( copy( $self->_abs_remote($remote_file),
647             $self->_abs_local($local_file) ) ) {
648 1         134 $self->{message} = sprintf("%s: %s", $remote_file, $!);
649 1         4 return;
650             }
651              
652 4         1320 return $local_file;
653             }
654              
655              
656             =head2 put( $local_file, [$remote_file] )
657              
658             put a file to mock FTP server
659             this methos is allowed to be overridden.
660              
661             =cut
662              
663              
664             =head2 mock_default_put( $local_file, [$remote_file] )
665              
666             default implementation for put. this method sholud be used in overridden method.
667              
668             =cut
669              
670             sub mock_default_put {
671 9     9 1 20 my ($self, $local_file, $remote_file) = @_;
672 9 100       335 $remote_file = basename($local_file) if ( !defined $remote_file );
673 9 100       46 unless ( copy( $self->_abs_local($local_file),
674             $self->_abs_remote($remote_file) ) ) {
675 1         312 carp "Cannot open Local file $remote_file: $!";
676 1         105 return;
677             }
678              
679 8         3156 return $remote_file;
680             }
681              
682             =head2 put_unique( $local_file, [$remote_file] )
683              
684             same as put() but if same file exists in server. rename to unique filename
685             (in this module, simply add suffix .1(.2, .3...). and suffix is limited to 1024)
686             this methos is allowed to be overridden.
687              
688             =cut
689              
690              
691             sub _unique_new_name {
692 2     2   5 my ($self, $remote_file) = @_;
693              
694 2         4 my $suffix = "";
695 2         4 my $newfile = $remote_file;
696 2         7 for ( my $i=1; $i<=1024; $i++ ) {
697 3 100       14 last if ( !-e $self->_abs_remote($newfile) );
698 1         3 $suffix = ".$i";
699 1         4 $newfile = $remote_file . $suffix;
700             }
701 2         7 return $newfile;
702             }
703              
704             =head2 mock_default_put_unique( $local_file, [$remote_file] )
705              
706             default implementation for put_unique. this method sholud be used in overridden method.
707              
708             =cut
709              
710             sub mock_default_put_unique {
711 2     2 1 5 my ($self, $local_file, $remote_file) = @_;
712 2 50       79 $remote_file = basename($local_file) if ( !defined $remote_file );
713              
714 2         9 my $newfile = $self->_unique_new_name($remote_file);
715 2 100       10 unless ( copy( $self->_abs_local($local_file),
716             $self->_abs_remote($newfile) ) ) {
717 1         292 carp "Cannot open Local file $remote_file: $!";
718 1         90 $self->{mock_unique_name} = undef;
719 1         5 return;
720             }
721 1         305 $self->{mock_unique_name} = $newfile;
722             }
723              
724              
725             =head2 append( $local_file, [$remote_file] )
726              
727             put a file to mock FTP server. if file already exists, append file contents in server file.
728             this methos is allowed to be overridden.
729              
730             =cut
731              
732              
733             =head2 mock_default_append( $local_file, [$remote_file] )
734              
735             default implementation for append. this method sholud be used in overridden method.
736              
737             =cut
738              
739             sub mock_default_append {
740 9     9 1 15 my ($self, $local_file, $remote_file) = @_;
741              
742 9 100       186 $remote_file = basename($local_file) if ( !defined $remote_file );
743 9         9 my $local_contents = eval { read_file( $self->_abs_local($local_file) ) };
  9         23  
744 9 100       950 if ( $@ ) {
745 1         97 carp "Cannot open Local file $remote_file: $!";
746 1         151 return;
747             }
748 8         21 write_file( $self->_abs_remote($remote_file), { append => 1 }, $local_contents);
749             }
750              
751             =head2 unique_name()
752              
753             return unique filename when put_unique() called.
754             this methos is allowed to be overridden.
755              
756             =cut
757              
758              
759             =head2 mock_default_unique_name()
760              
761             default implementation for unique_name. this method sholud be used in overridden method.
762              
763             =cut
764              
765             sub mock_default_unique_name {
766 2     2 1 5 my($self) = @_;
767              
768 2         10 return $self->{mock_unique_name};
769             }
770              
771             =head2 mdtm( $file )
772              
773             returns file modification time in remote (mock) server.
774             this methos is allowed to be overridden.
775              
776             =cut
777              
778             =head2 mock_default_mdtm()
779              
780             default implementation for mdtm. this method sholud be used in overridden method.
781              
782             =cut
783              
784             sub mock_default_mdtm {
785 1     1 1 2 my ($self, $filename) = @_;
786 1         6 my $mdtm = ( stat $self->_abs_remote($filename) )[9];
787 1         10 return $mdtm;
788             }
789              
790             =head2 size( $file )
791              
792             returns filesize in remote (mock) server.
793             this methos is allowed to be overridden.
794              
795             =cut
796              
797              
798             =head2 mock_default_size( $file )
799              
800             default implementation for size. this method sholud be used in overridden method.
801              
802             =cut
803              
804             sub mock_default_size {
805 1     1 1 3 my ($self, $filename) = @_;
806 1         5 my $size = ( stat $self->_abs_remote($filename) )[7];
807 1         10 return $size;
808             }
809              
810             =head2 supported( $cmd )
811              
812             supported.
813             default implementation is 'do nothing'. this method is allowed to be overridden.
814              
815             =cut
816              
817              
818             =head2 mock_default_supported( $cmd )
819              
820             default implementation for supported. this method sholud be used in overridden method.
821              
822             =cut
823              
824             sub mock_default_supported {
825 1     1 1 4 my ($self, $cmd) = @_;
826 1         6 return 1;
827             }
828              
829              
830             =head2 hash( [$filehandle_glob_ref], [$bytes_per_hash_mark] )
831              
832             hash.
833             default implementation is 'do nothing'. this method is allowed to be overridden.
834              
835             =cut
836              
837              
838             =head2 mock_default_hash( [$filehandle_glob_ref], [$bytes_per_hash_mark] )
839              
840             default implementation for hash. this method sholud be used in overridden method.
841              
842             =cut
843              
844             sub mock_default_hash {
845 1     1 1 2 my ($self, $filehandle_glob_ref, $bytes_per_hash_mark) = @_;
846 1         4 return 1;
847             }
848              
849              
850             =head2 feature( $cmd )
851              
852             reature. currently returns list of $cmd.
853             this method is allowed to be overridden.
854              
855             =cut
856              
857              
858             =head2 mock_default_feature( $cmd )
859              
860             default implementation for feature. this method sholud be used in overridden method.
861              
862             =cut
863              
864             sub mock_default_feature {
865 1     1 1 3 my ($self, $cmd) = @_;
866 1         13 return ($cmd);
867             }
868              
869             =head2 nlst( [$dir] )
870              
871             nlst.
872             default implementation is 'do nothing'. this method is allowed to be overridden.
873              
874             =cut
875              
876             =head2 mock_default_nlst( [$dir] )
877              
878             default implementation for nlst. this method sholud be used in overridden method.
879              
880             =cut
881              
882             sub mock_default_nlst {
883 1     1 1 2 my ($self, $dir) = @_;
884 1         3 return 1;
885             }
886              
887             =head2 list( [$dir] )
888              
889             list.
890             default implementation is 'do nothing'. this method is allowed to be overridden.
891              
892             =cut
893              
894              
895             =head2 mock_default_list( [$dir] )
896              
897             default implementation for list. this method sholud be used in overridden method.
898              
899             =cut
900              
901             sub mock_default_list {
902 1     1 1 3 my ($self, $dir) = @_;
903 1         4 return 1;
904             }
905              
906             =head2 retr( $file )
907              
908             retr.
909             default implementation is 'do nothing'. this method is allowed to be overridden.
910              
911             =cut
912              
913              
914             =head2 mock_default_retr($file)
915              
916             default implementation for retr. this method sholud be used in overridden method.
917              
918             =cut
919              
920             sub mock_default_retr {
921 1     1 1 2 my ($self, $file) = @_;
922 1         3 return 1;
923             }
924              
925             =head2 stor( $file )
926              
927             stor.
928             default implementation is 'do nothing'. this method is allowed to be overridden.
929              
930             =cut
931              
932              
933             =head2 mock_default_stor( $file )
934              
935             default implementation for stor. this method sholud be used in overridden method.
936              
937             =cut
938              
939             sub mock_default_stor {
940 1     1 1 2 my ($self, $file) = @_;
941 1         3 return 1;
942             }
943              
944             =head2 stou( $file )
945              
946             stou. currently do_nothing.
947              
948             =cut
949              
950              
951             =head2 mock_default_stou( $file )
952              
953             default implementation for stor. this method sholud be used in overridden method.
954              
955             =cut
956              
957             sub mock_default_stou {
958 1     1 1 3 my ($self, $file) = @_;
959 1         2 return 1;
960             }
961              
962             =head2 appe( $file )
963              
964             appe.
965             default implementation is 'do nothing'. this method is allowed to be overridden.
966              
967             =cut
968              
969              
970             =head2 mock_default_appe( $file )
971              
972             default implementation for appe. this method sholud be used in overridden method.
973              
974             =cut
975              
976             sub mock_default_appe {
977 1     1 1 3 my ($self, $file) = @_;
978 1         3 return 1;
979             }
980              
981             =head2 port( $port_no )
982              
983             specify data connection to port-mode.
984              
985             after called this method, mock_connection_mode() returns 'port' and
986             mock_port_no() returns specified $port_no.
987              
988             this methos is allowed to be overridden.
989              
990             =cut
991              
992              
993             =head2 mock_default_port( $port_no )
994              
995             default implementation for port. this method sholud be used in overridden method.
996              
997             =cut
998              
999             sub mock_default_port {
1000 1     1 1 3 my ($self, $port_no) = @_;
1001 1         2 $self->{mock_connection_mode} = 'port';
1002 1         4 $self->{mock_port_no} = $port_no;
1003             }
1004              
1005             =head2 pasv()
1006              
1007             specify data connection to passive-mode.
1008             after called this method, mock_connection_mode() returns 'pasv' and
1009             mock_port_no() returns ''
1010              
1011             this methos is allowed to be overridden.
1012              
1013             =cut
1014              
1015              
1016             =head2 mock_default_pasv()
1017              
1018             default implementation for pasv. this method sholud be used in overridden method.
1019              
1020             =cut
1021              
1022             sub mock_default_pasv {
1023 1     1 1 3 my ($self) = @_;
1024 1         2 $self->{mock_connection_mode} = 'pasv';
1025 1         3 $self->{mock_port_no} = '';
1026             }
1027              
1028             =head2 pasv_xfer( $src_file, $dest_server, [$dest_file] )
1029              
1030             pasv_xfer.
1031             default implementation is 'do nothing'. this method is allowed to be overridden.
1032              
1033             =cut
1034              
1035              
1036             =head2 mock_default_pasv_xfer( $src_file, $dest_server, [$dest_file] )
1037              
1038             default implementation for psv_xfer. this method sholud be used in overridden method.
1039              
1040             =cut
1041              
1042             sub mock_default_pasv_xfer {
1043 1     1 1 2 my ($self) = @_;
1044 1         4 return 1;
1045             }
1046              
1047              
1048             =head2 pasv_xfer_unique( $src_file, $dest_server, [$dest_file] )
1049              
1050             pasv_xfer_unique.
1051             default implementation is 'do nothing'. this method is allowed to be overridden.
1052              
1053             =cut
1054              
1055              
1056             =head2 mock_default_pasv_xfer_unique( $src_file, $dest_server, [$dest_file] )
1057              
1058             default implementation for psv_xfer_unique. this method sholud be used in overridden method.
1059              
1060             =cut
1061              
1062             sub mock_default_pasv_xfer_unique {
1063 1     1 1 4 my ($self) = @_;
1064 1         14 return 1;
1065             }
1066              
1067             =head2 pasv_wait( $non_pasv_server )
1068              
1069             pasv_wait.
1070             default implementation is 'do nothing'. this method is allowed to be overridden.
1071              
1072             =cut
1073              
1074              
1075             =head2 mock_default_pasv_wait( $non_pasv_server )
1076              
1077             default implementation for pasv_wait. this method sholud be used in overridden method.
1078              
1079             =cut
1080              
1081             sub mock_default_pasv_wait {
1082 1     1 1 2 my ($self) = @_;
1083 1         3 return 1;
1084             }
1085              
1086              
1087             =head2 abort()
1088              
1089             abort.
1090             default implementation is 'do nothing'. this method is allowed to be overridden.
1091              
1092             =cut
1093              
1094              
1095             =head2 mock_default_abort()
1096              
1097             default implementation for abort. this method sholud be used in overridden method.
1098              
1099             =cut
1100              
1101             sub mock_default_abort {
1102 0     0 1 0 my ($self) = @_;
1103 0         0 return 1;
1104             }
1105              
1106             =head2 quit()
1107              
1108             quit.
1109             default implementation is 'do nothing'. this method is allowed to be overridden.
1110              
1111             =cut
1112              
1113              
1114             =head2 mock_default_quit()
1115              
1116             default implementation for quit. this method sholud be used in overridden method.
1117              
1118             =cut
1119              
1120             sub mock_default_quit {
1121 9     9 1 16 my ($self) = @_;
1122 9         17 return 1;
1123             }
1124              
1125              
1126             =head2 quot( $cmd, @args )
1127              
1128             quot.
1129             default implementation is 'do nothing'. this method is allowed to be overridden.
1130              
1131             =cut
1132              
1133              
1134             =head2 mock_default_quot( $cmd, @args )
1135              
1136             default implementation for quot. this method sholud be used in overridden method.
1137              
1138             =cut
1139              
1140             sub mock_default_quot {
1141 1     1 1 3 my ($self) = @_;
1142 1         2 return 1;
1143             }
1144              
1145              
1146             =head2 close()
1147              
1148             close connection mock FTP server.
1149             default implementation is 'do nothing'. this method is allowed to be overridden.
1150              
1151             =cut
1152              
1153              
1154             =head2 mock_default_close()
1155              
1156             default implementation for close. this method sholud be used in overridden method.
1157              
1158             =cut
1159              
1160             sub mock_default_close {
1161 3     3 1 6 my ($self) = @_;
1162 3         10 return 1;
1163             }
1164              
1165             sub _mock_abs2rel {
1166 52     52   76 my ($self, $path) = @_;
1167              
1168 52 100 100     515 if (defined $path && $path =~ /^$self->{mock_server_root}/ ) { #absolute path
1169 6         105 $path =~ s/^$self->{mock_server_root}//;
1170             }
1171 52         164 return $path;
1172             }
1173              
1174             sub _relative_remote {
1175 8     8   15 my ($self, $path) = @_;
1176              
1177 8         30 $path = $self->_mock_abs2rel($path);
1178              
1179 8 100       30 return $self->mock_pwd if !defined $path;
1180 6         24 return catdir($self->mock_pwd, $path);
1181             }
1182              
1183              
1184             sub _abs_remote {
1185 44     44   67 my ($self, $remote_path) = @_;
1186              
1187 44 100       12082 my $remote_dir = dirname($remote_path) eq curdir() ? $self->{mock_cwd} : dirname($remote_path) ;
1188 44         133 $remote_dir = $self->_mock_abs2rel($remote_dir);
1189              
1190 44         3523 return catfile($self->{mock_physical_root}, $remote_dir, basename($remote_path))
1191             }
1192              
1193             sub _abs_local {
1194 25     25   48 my ($self, $local_path) = @_;
1195              
1196 25         34 my $root = rootdir();
1197 25 100       166 return $local_path if ( $local_path =~ m{^$root} );
1198              
1199 22 100       866 my $local_dir = dirname($local_path) eq curdir() ? getcwd() : dirname($local_path);
1200 22         577 return catfile($local_dir, basename($local_path));
1201             }
1202              
1203             =head2 message()
1204              
1205             return messages from mock FTP server
1206             this method is allowed to be overridden.
1207              
1208             =cut
1209              
1210             sub message {
1211 51     51 1 216 my ($self) = @_;
1212              
1213 51         120 $self->_push_mock_command_history('message', @_);
1214             # do not clear $self->{message}, that's why this definition is still remain(not in AUTOLOAD)
1215 51 100       171 goto &{ $self->{mock_override}->{message} } if ( exists $self->{mock_override}->{message} );
  2         9  
1216              
1217 49         108 return $self->mock_default_message();
1218             }
1219              
1220             =head2 mock_default_message()
1221              
1222             default implementation for message. this method sholud be used in overridden method.
1223              
1224             =cut
1225              
1226             sub mock_default_message {
1227 49     49 1 67 my ($self) = @_;
1228 49         188 return $self->{message};
1229             }
1230              
1231             sub _mock_cwd {
1232 140     140   185 my ($self) = @_;
1233 140 50       2074 return (defined $self->{mock_cwd}) ? $self->{mock_cwd} : "";
1234             }
1235              
1236              
1237             sub import {
1238 30     30   6199 my ($package, @args) = @_;
1239 30         15664 for my $arg ( @args ) {
1240 2 50       11 _mock_intercept() if ( $arg eq 'intercept' );
1241             }
1242             }
1243              
1244             sub _mock_intercept {
1245 18     18   25199 use Net::FTP;
  18         965671  
  18         1389  
1246 18     18   219 no warnings 'redefine';
  18         32  
  18         5754  
1247             *Net::FTP::new = sub {
1248 2     2   2405 my $class = shift;#discard $class
1249 2         25 return Test::Mock::Net::FTP->new(@_);
1250             }
1251 2     2   117 }
1252              
1253 0     0   0 sub DESTROY {} #for AUTOLOAD
1254              
1255             sub AUTOLOAD {
1256 255     255   22759 my ($self) = @_;
1257 255         397 my $method = our $AUTOLOAD;
1258 255         1301 $method =~ s/.*:://o;
1259              
1260 255         1999 my @methods = (
1261             'unique_name', 'size', 'mdtm',
1262             'message', 'cwd', 'cdup',
1263             'put', 'append', 'put_unique',
1264             'get', 'rename', 'delete',
1265             'mkdir', 'rmdir', 'port',
1266             'pasv', 'binary', 'ascii',
1267             'quit', 'close', 'abort',
1268             'site', 'hash', 'alloc',
1269             'nlst', 'list', 'retr',
1270             'stou', 'stor', 'appe',
1271             'quot', 'supported', 'authorize',
1272             'feature', 'restart', 'pasv_xfer',
1273             'pasv_xfer_unique', 'pasv_wait', 'ls',
1274             'dir', 'pwd',
1275             );
1276              
1277 255 50       431 if( grep{ $_ eq $method } @methods ) {
  10455         14672  
1278 255         649 $self->_push_mock_command_history($method, @_);
1279 255         451 $self->{message} = '';
1280              
1281 255 100       827 if ( exists $self->{mock_override}->{$method} ) {# override in mock_prepare
1282 125         129 goto &{ $self->{mock_override}->{$method} }
  125         682  
1283             }
1284             else { #not overridden (call default method)
1285 130         157 goto &{ "mock_default_$method" };
  130         1024  
1286             }
1287             }
1288             }
1289              
1290             1;
1291              
1292              
1293             =head1 AUTHOR
1294              
1295             Takuya Tsuchida Etsucchi at cpan.orgE
1296              
1297             =head1 SEE ALSO
1298              
1299             L
1300              
1301             =head1 REPOSITORY
1302              
1303             L
1304              
1305              
1306             =head1 COPYRIGHT AND LICENSE
1307              
1308             Copyright (c) 2009-2011 Takuya Tsuchida
1309              
1310             This library is free software; you can redistribute it and/or modify
1311             it under the same terms as Perl itself.
1312              
1313             =cut