Update CPANPLUS::Dist::Build to 0.08
[perl.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 ### make sure to add dslip data, so CPANPLUS doesn't try to find
43 ### it in another module in the package, for which it needs the
44 ### module tree
45 my $Mod = CPANPLUS::Module::Fake->new(
46                 module  => 'Foo::Bar',
47                 path    => 'src',
48                 author  => CPANPLUS::Module::Author::Fake->new,
49                 package => 'Foo-Bar-0.01.tar.gz',
50                 dslip   => 'RdpO?',
51             );
52
53 $Conf->set_conf( base       => 'dummy-cpanplus' );
54 $Conf->set_conf( dist_type  => '' );
55 $Conf->set_conf( verbose    => $Verbose );
56 $Conf->set_conf( signature  => 0 );
57 ### running tests will mess with the test output so skip 'm
58 $Conf->set_conf( skiptest   => 1 );
59
60 ### dmq tells us that we should run with /nologo
61 ### if using nmake, as it's very noise otherwise.
62 ### XXX copied from CPANPLUS' test include file!
63 {   my $make = $Conf->get_program('make');
64     if( $make and basename($make) =~ /^nmake/i and
65         $make !~ m|/nologo|
66     ) {
67         $make .= ' /nologo';
68         $Conf->set_program( make => $make );
69     }
70 }
71     
72
73                 # path, cc needed?
74 my %Map     = ( noxs    => 0,
75                 xs      => 1 
76             );        
77
78
79 ### Disable certain possible settings, so we dont accidentally
80 ### touch anything outside our sandbox
81 {   
82     ### set buildflags to install in our dummy perl dir
83     $Conf->set_conf( buildflags => "install_base=$Lib" );
84     
85     ### don't start sending test reports now... ###
86     $CB->_callbacks->send_test_report( sub { 0 } );
87     $Conf->set_conf( cpantest => 0 );
88     
89     ### we dont need sudo -- we're installing in our own sandbox now
90     $Conf->set_program( sudo => undef );
91 }
92
93 use_ok( $Class );
94
95 ok( $Class->format_available,   "Format is available" );
96
97
98 while( my($path,$need_cc) = each %Map ) {
99
100     my $mod = $Mod->clone;
101     ok( $mod,                   "Module object created for '$path'" );        
102                 
103     ### set the fetch location -- it's local
104     {   my $where = File::Spec->rel2abs(
105                             File::Spec->catfile( $Src, $path, $mod->package )
106                         );
107                         
108         $mod->status->fetch( $where );
109
110         ok( -e $where,          "   Tarball '$where' exists" );
111     }
112
113     ok( $mod->prepare,          "   Preparing module" );
114
115     ok( $mod->status->dist_cpan,    
116                                 "   Dist registered as status" );
117
118     isa_ok( $mod->status->dist_cpan, $Class );
119
120     ok( $mod->status->dist_cpan->status->prepared,
121                                 "   Prepared status registered" );
122     is( $mod->status->dist_cpan->status->distdir, $mod->status->extract,
123                                 "   Distdir status registered properly" );
124
125
126     is( $mod->status->installer_type, INSTALLER_BUILD, 
127                                 "   Proper installer type found" );
128
129
130     ### we might not have a C compiler
131     SKIP: {
132         skip("The CC compiler listed in Config.pm is not available " .
133              "-- skipping compile tests", 5) if $need_cc && !$Have_CC;
134         skip("Module::Build is not compiled with C support ".
135              "-- skipping compile tests", 5) 
136              unless eval { require Module::Build::ConfigData;
137              Module::Build::ConfigData->feature('C_support') };
138
139         ok( $mod->create( ),    "Creating module" );
140         ok( $mod->status->dist_cpan->status->created,
141                                 "   Created status registered" );
142
143         ### install tests
144         SKIP: {
145             skip("Install tests require Module::Build 0.2606 or higher", 2)
146                 unless $Module::Build::VERSION >= '0.2606';
147         
148             ### flush the lib cache
149             ### otherwise, cpanplus thinks the module's already installed
150             ### since the blib is already in @INC
151             $CB->_flush( list => [qw|lib|] );
152         
153             ### force the install, make sure the Dist::Build->install()
154             ### sub gets called
155             ok( $mod->install( force => 1 ),
156                                 "Installing module" ); 
157             ok( $mod->status->installed,    
158                                 "   Status says module installed" );
159         }
160
161         SKIP: {
162             my $minversion = 0.2609;
163             skip(qq[Uninstalling requires at least Module::Build $minversion], 1)
164               unless eval { Module::Build->VERSION($minversion); 1 };
165
166             # The installation directory actually needs to be in @INC
167             # in order to test uninstallation
168             {   my $libdir = File::Spec->catdir($Lib, 'lib', 'perl5');
169                 
170                 # lib.pm is documented to require unix-style paths
171                 $libdir = VMS::Filespec::unixify($libdir) if $^O eq 'VMS';
172
173                 'lib'->import( $libdir );
174             }
175
176             # EU::Installed and CP+::M are only capable of searching
177             # for modules in the core directories.  We need to fake
178             # them out with our own subs here.
179             my $packlist = find_module($mod->name . '::.packlist');
180             ok $packlist, "Found packlist";
181             
182             my $p = ExtUtils::Packlist->new($packlist);
183             ok keys(%$p) > 0, "Packlist contains entries";
184
185             local *CPANPLUS::Module::installed_version = sub {1};
186             local *CPANPLUS::Module::packlist = sub { [$p] };
187             local *ExtUtils::Installed::files = sub { keys %$p };
188             
189             ok( $mod->uninstall,"Uninstalling module" );
190         }
191     }
192
193     ### throw away all the extracted stuff
194     $Utils->_rmdir( dir => $Conf->get_conf('base') );
195 }
196
197 ### test ENV setting while running Build.PL code
198 {   ### use print() not die() -- we're redirecting STDERR in tests!
199     my $env     = 'ENV_CPANPLUS_IS_EXECUTING';
200     my $clone   = $Mod->clone;
201     
202     ok( $clone,                 'Testing ENV settings $dist->prepare' );
203     
204     $clone->status->fetch( File::Spec->catfile($Src, 'noxs', $clone->package) );
205     ok( $clone->extract,        '   Files extracted' );
206     
207     ### write our own Build.PL file    
208     my $build_pl = BUILD_PL->( $clone->status->extract );
209     {   my $fh   = OPEN_FILE->( $build_pl, '>' );
210         print $fh "die qq[ENV=\$ENV{$env}\n];";
211         close $fh;
212     }
213     ok( -e $build_pl,           "   File exists" );
214
215     ### clear errors    
216     CPANPLUS::Error->flush;
217
218     ### since we're die'ing in the Build.PL, localize 
219     ### $CPANPLUS::Error::ERROR_FH and redirect to devnull
220     ### so we dont spam the result through the test 
221     ### as this is expected behaviour after all.
222     my $rv = do {
223         local *CPANPLUS::Error::ERROR_FH;
224         open $CPANPLUS::Error::ERROR_FH, ">", File::Spec->devnull;
225         $clone->prepare( force => 1 ) 
226     };
227     ok( !$rv,                   '   $mod->prepare failed' );
228
229     my $re = quotemeta( $build_pl );
230     like( CPANPLUS::Error->stack_as_string, qr/ENV=$re/,
231                                 "   \$ENV $env set correctly during execution");
232
233     ### and the ENV var should no longer be set now
234     ok( !$ENV{$env},            "   ENV var now unset" );
235 }    
236
237
238 sub find_module {
239   my $module = shift;
240
241   ### Don't add the .pm yet, in case it's a packlist or something 
242   ### like ExtUtils::xsubpp.
243   my $file = File::Spec->catfile( split m/::/, $module );
244   my $candidate;
245   foreach (@INC) {
246     if (-e ($candidate = File::Spec->catfile($_, $file))
247         or
248         -e ($candidate = File::Spec->catfile($_, "$file.pm"))
249         or
250         -e ($candidate = File::Spec->catfile($_, 'auto', $file))
251         or
252         -e ($candidate = File::Spec->catfile($_, 'auto', "$file.pm"))
253         or
254         -e ($candidate = File::Spec->catfile($_, $Config{archname},
255                                              'auto', $file))
256         or
257         -e ($candidate = File::Spec->catfile($_, $Config{archname},
258                                              'auto', "$file.pm"))) {
259       return $candidate;
260     }
261   }
262   return;
263 }
264
265
266 # Local variables:
267 # c-indentation-style: bsd
268 # c-basic-offset: 4
269 # indent-tabs-mode: nil
270 # End:
271 # vim: expandtab shiftwidth=4: