This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
490420e0486457fcc03dfa749f845873b9cbc48c
[perl5.git] / lib / CPANPLUS / Dist / Build / t / 02_CPANPLUS-Dist-Build.t
1 ### make sure we can find our conf.pl file
2 BEGIN { 
3     use FindBin; 
4     require "$FindBin::Bin/inc/conf.pl";
5 }
6
7 use strict;
8 use CPANPLUS::Configure;
9 use CPANPLUS::Backend;
10 use CPANPLUS::Internals::Constants;
11 use CPANPLUS::Module::Fake;
12 use CPANPLUS::Module::Author::Fake;
13
14 use Config;
15 use Test::More      'no_plan';
16 use File::Basename  qw[basename];
17 use Data::Dumper;
18 use Config;
19 use IPC::Cmd        'can_run';
20
21 $SIG{__WARN__} = sub {warn @_ unless @_ && $_[0] =~ /redefined|isn't numeric/};
22
23 # Load these two modules in advance, even though they would be
24 # auto-loaded, because we want to override some of their subs.
25 use ExtUtils::Packlist;
26 use ExtUtils::Installed;
27
28 my $Class   = 'CPANPLUS::Dist::Build';
29 my $Utils   = 'CPANPLUS::Internals::Utils';
30 my $Have_CC =  can_run($Config{'cc'} )? 1 : 0;
31
32
33 my $Lib     = File::Spec->rel2abs(File::Spec->catdir( qw[dummy-perl] ));
34 my $Src     = File::Spec->rel2abs(File::Spec->catdir( qw[src] ));
35
36 my $Verbose = @ARGV ? 1 : 0;
37 my $CB      = CPANPLUS::Backend->new;
38 my $Conf    = $CB->configure_object;
39
40
41 ### create a fake object, so we don't use the actual module tree
42 my $Mod = CPANPLUS::Module::Fake->new(
43                 module  => 'Foo::Bar',
44                 path    => 'src',
45                 author  => CPANPLUS::Module::Author::Fake->new,
46                 package => 'Foo-Bar-0.01.tar.gz',
47             );
48
49 $Conf->set_conf( base       => 'dummy-cpanplus' );
50 $Conf->set_conf( dist_type  => '' );
51 $Conf->set_conf( verbose    => $Verbose );
52 $Conf->set_conf( signature  => 0 );
53 ### running tests will mess with the test output so skip 'm
54 $Conf->set_conf( skiptest   => 1 );
55
56 ### dmq tells us that we should run with /nologo
57 ### if using nmake, as it's very noise otherwise.
58 ### XXX copied from CPANPLUS' test include file!
59 {   my $make = $Conf->get_program('make');
60     if( $make and basename($make) =~ /^nmake/i and
61         $make !~ m|/nologo|
62     ) {
63         $make .= ' /nologo';
64         $Conf->set_program( make => $make );
65     }
66 }
67     
68
69                 # path, cc needed?
70 my %Map     = ( noxs    => 0,
71                 xs      => 1 
72             );        
73
74
75 ### Disable certain possible settings, so we dont accidentally
76 ### touch anything outside our sandbox
77 {   
78     ### set buildflags to install in our dummy perl dir
79     $Conf->set_conf( buildflags => "install_base=$Lib" );
80     
81     ### don't start sending test reports now... ###
82     $CB->_callbacks->send_test_report( sub { 0 } );
83     $Conf->set_conf( cpantest => 0 );
84     
85     ### we dont need sudo -- we're installing in our own sandbox now
86     $Conf->set_program( sudo => undef );
87 }
88
89 use_ok( $Class );
90
91 ok( $Class->format_available,   "Format is available" );
92
93
94 while( my($path,$need_cc) = each %Map ) {
95
96     my $mod = $Mod->clone;
97     ok( $mod,                   "Module object created for '$path'" );        
98                 
99     ### set the fetch location -- it's local
100     {   my $where = File::Spec->rel2abs(
101                             File::Spec->catdir( $Src, $path, $mod->package )
102                         );
103                         
104         $mod->status->fetch( $where );
105
106         ok( -e $where,          "   Tarball '$where' exists" );
107     }
108
109     ok( $mod->prepare,          "   Preparing module" );
110
111     ok( $mod->status->dist_cpan,    
112                                 "   Dist registered as status" );
113
114     isa_ok( $mod->status->dist_cpan, $Class );
115
116     ok( $mod->status->dist_cpan->status->prepared,
117                                 "   Prepared status registered" );
118     is( $mod->status->dist_cpan->status->distdir, $mod->status->extract,
119                                 "   Distdir status registered properly" );
120
121
122     is( $mod->status->installer_type, INSTALLER_BUILD, 
123                                 "   Proper installer type found" );
124
125
126     ### we might not have a C compiler
127     SKIP: {
128         skip("The CC compiler listed in Config.pm is not available " .
129              "-- skipping compile tests", 5) if $need_cc && !$Have_CC;
130         skip("Module::Build is not compiled with C support ".
131              "-- skipping compile tests", 5) 
132              unless Module::Build->_mb_feature('C_support');
133
134         ok( $mod->create( ),    "Creating module" );
135         ok( $mod->status->dist_cpan->status->created,
136                                 "   Created status registered" );
137
138         ### install tests
139         SKIP: {
140             skip("Install tests require Module::Build 0.2606 or higher", 2)
141                 unless $Module::Build::VERSION >= '0.2606';
142         
143             ### flush the lib cache
144             ### otherwise, cpanplus thinks the module's already installed
145             ### since the blib is already in @INC
146             $CB->_flush( list => [qw|lib|] );
147         
148             ### force the install, make sure the Dist::Build->install()
149             ### sub gets called
150             ok( $mod->install( force => 1 ),
151                                 "Installing module" ); 
152             ok( $mod->status->installed,    
153                                 "   Status says module installed" );
154         }
155
156         SKIP: {
157             my $minversion = 0.2609;
158             skip(qq[Uninstalling requires at least Module::Build $minversion], 1)
159               unless eval { Module::Build->VERSION($minversion); 1 };
160
161             # The installation directory actually needs to be in @INC
162             # in order to test uninstallation
163             'lib'->import( File::Spec->catdir($Lib, 'lib', 'perl5') );
164
165             # EU::Installed and CP+::M are only capable of searching
166             # for modules in the core directories.  We need to fake
167             # them out with our own subs here.
168             my $packlist = find_module($mod->name . '::.packlist');
169             ok $packlist, "Found packlist";
170             
171             my $p = ExtUtils::Packlist->new($packlist);
172             ok keys(%$p) > 0, "Packlist contains entries";
173
174             local *CPANPLUS::Module::installed_version = sub {1};
175             local *CPANPLUS::Module::packlist = sub { [$p] };
176             local *ExtUtils::Installed::files = sub { keys %$p };
177             
178             ok( $mod->uninstall,"Uninstalling module" );
179         }
180     }
181
182     ### throw away all the extracted stuff
183     $Utils->_rmdir( dir => $Conf->get_conf('base') );
184 }
185
186 ### test ENV setting while running Build.PL code
187 {   ### use print() not die() -- we're redirecting STDERR in tests!
188     my $env     = 'ENV_CPANPLUS_IS_EXECUTING';
189     my $clone   = $Mod->clone;
190     
191     ok( $clone,                 'Testing ENV settings $dist->prepare' );
192     
193     $clone->status->fetch( File::Spec->catfile($Src, 'noxs', $clone->package) );
194     ok( $clone->extract,        '   Files extracted' );
195     
196     ### write our own Build.PL file    
197     my $build_pl = BUILD_PL->( $clone->status->extract );
198     {   my $fh   = OPEN_FILE->( $build_pl, '>' );
199         print $fh "die qq[ENV=\$ENV{$env}\n];";
200         close $fh;
201     }
202     ok( -e $build_pl,           "   File exists" );
203
204     ### clear errors    
205     CPANPLUS::Error->flush;
206
207     ### since we're die'ing in the Build.PL, do a local *STDERR,
208     ### so we dont spam the result through the test -- this is expected
209     ### behaviour after all.
210     ### also quell the warning for print() on unopened fh...
211     my $rv = do { 
212                 local $^W;
213                 local *STDERR; 
214                 $clone->prepare( force => 1 ) 
215             };
216     ok( !$rv,                   '   $mod->prepare failed' );
217
218     my $re = quotemeta( $build_pl );
219     like( CPANPLUS::Error->stack_as_string, qr/ENV=$re/,
220                                 "   \$ENV $env set correctly during execution");
221
222     ### and the ENV var should no longer be set now
223     ok( !$ENV{$env},            "   ENV var now unset" );
224 }    
225
226
227 sub find_module {
228   my $module = shift;
229
230   ### Don't add the .pm yet, in case it's a packlist or something 
231   ### like ExtUtils::xsubpp.
232   my $file = File::Spec->catfile( split m/::/, $module );
233   my $candidate;
234   foreach (@INC) {
235     if (-e ($candidate = File::Spec->catdir($_, $file))
236         or
237         -e ($candidate = File::Spec->catdir($_, "$file.pm"))
238         or
239         -e ($candidate = File::Spec->catdir($_, 'auto', $file))
240         or
241         -e ($candidate = File::Spec->catdir($_, 'auto', "$file.pm"))) {
242       return $candidate;
243     }
244   }
245   return;
246 }
247
248
249 # Local variables:
250 # c-indentation-style: bsd
251 # c-basic-offset: 4
252 # indent-tabs-mode: nil
253 # End:
254 # vim: expandtab shiftwidth=4: