[patch@31988] Revised Module::Build fixes for VMS.
[p5sagit/p5-mst-13.2.git] / lib / Module / Build / t / metadata.t
1 #!/usr/bin/perl -w
2
3 use strict;
4 use lib $ENV{PERL_CORE} ? '../lib/Module/Build/t/lib' : 't/lib';
5 use MBTest tests => 47;
6
7 use Cwd ();
8 my $cwd = Cwd::cwd;
9 my $tmp = File::Spec->catdir( $cwd, 't', '_tmp' );
10
11
12 use Module::Build;
13 use Module::Build::ConfigData;
14 my $has_YAML = Module::Build::ConfigData->feature('YAML_support');
15
16
17 use DistGen;
18 my $dist = DistGen->new( dir => $tmp );
19 $dist->change_file( 'Build.PL', <<"---" );
20
21 my \$builder = Module::Build->new(
22     module_name   => '@{[$dist->name]}',
23     dist_version  => '3.14159265',
24     dist_author   => [ 'Simple Simon <ss\@somewhere.priv>' ],
25     dist_abstract => 'Something interesting',
26     license       => 'perl',
27 );
28
29 \$builder->create_build_script();
30 ---
31 $dist->regen;
32
33 my $simple_file = 'lib/Simple.pm';
34 my $simple2_file = 'lib/Simple2.pm';
35
36    #TODO:
37    # Traditional VMS will return the file in in lower case, and is_deeply
38    # does exact case comparisons.
39    # When ODS-5 support is active for preserved case file names, this will
40    # need to be changed.
41    if ($^O eq 'VMS') {
42        $simple_file = lc($simple_file);
43        $simple2_file = lc($simple2_file);
44    }
45
46
47 chdir( $dist->dirname ) or die "Can't chdir to '@{[$dist->dirname]}': $!";
48
49 use Module::Build;
50 my $mb = Module::Build->new_from_context;
51
52 ##################################################
53 #
54 # Test for valid META.yml
55
56 SKIP: {
57   skip( 'YAML_support feature is not enabled', 8 ) unless $has_YAML;
58
59   require YAML;
60   require YAML::Node;
61   my $node = YAML::Node->new({});
62   $node = $mb->prepare_metadata( $node );
63
64   # exists() doesn't seem to work here
65   ok defined( $node->{name} ),     "'name' field present in META.yml";
66   ok defined( $node->{version} ),  "'version' field present in META.yml";
67   ok defined( $node->{abstract} ), "'abstract' field present in META.yml";
68   ok defined( $node->{author} ),   "'author' field present in META.yml";
69   ok defined( $node->{license} ),  "'license' field present in META.yml";
70   ok defined( $node->{generated_by} ),
71       "'generated_by' field present in META.yml";
72   ok defined( $node->{'meta-spec'}{version} ),
73       "'meta-spec' -> 'version' field present in META.yml";
74   ok defined( $node->{'meta-spec'}{url} ),
75       "'meta-spec' -> 'url' field present in META.yml";
76
77   # TODO : find a way to test for failure when above fields are not present
78 }
79
80 $dist->clean;
81
82
83 ##################################################
84 #
85 # Tests to ensure that the correct packages and versions are
86 # recorded for the 'provides' field of META.yml
87
88 my $provides; # Used a bunch of times below
89
90 sub new_build { return Module::Build->new_from_context( quiet => 1, @_ ) }
91
92 ############################## Single Module
93
94 # File with corresponding package (w/ or w/o version)
95 # Simple.pm => Simple v1.23
96
97 $dist->change_file( 'lib/Simple.pm', <<'---' );
98 package Simple;
99 $VERSION = '1.23';
100 ---
101 $dist->regen( clean => 1 );
102 $mb = new_build();
103 is_deeply($mb->find_dist_packages,
104           {'Simple' => {file => $simple_file,
105                         version => '1.23'}});
106
107 $dist->change_file( 'lib/Simple.pm', <<'---' );
108 package Simple;
109 ---
110 $dist->regen( clean => 1 );
111 $mb = new_build();
112 is_deeply($mb->find_dist_packages,
113           {'Simple' => {file => $simple_file}});
114
115 # File with no corresponding package (w/ or w/o version)
116 # Simple.pm => Foo::Bar v1.23
117
118 $dist->change_file( 'lib/Simple.pm', <<'---' );
119 package Foo::Bar;
120 $VERSION = '1.23';
121 ---
122 $dist->regen( clean => 1 );
123 $mb = new_build();
124 is_deeply($mb->find_dist_packages,
125           {'Foo::Bar' => { file => $simple_file,
126                            version => '1.23' }});
127
128 $dist->change_file( 'lib/Simple.pm', <<'---' );
129 package Foo::Bar;
130 ---
131 $dist->regen( clean => 1 );
132 $mb = new_build();
133 is_deeply($mb->find_dist_packages,
134           {'Foo::Bar' => { file => $simple_file}});
135
136
137 # Single file with multiple differing packages (w/ or w/o version)
138 # Simple.pm => Simple
139 # Simple.pm => Foo::Bar
140
141 $dist->change_file( 'lib/Simple.pm', <<'---' );
142 package Simple;
143 $VERSION = '1.23';
144 package Foo::Bar;
145 $VERSION = '1.23';
146 ---
147 $dist->regen( clean => 1 );
148 $mb = new_build();
149 is_deeply($mb->find_dist_packages,
150           {'Simple'   => { file => $simple_file,
151                            version => '1.23' },
152            'Foo::Bar' => { file => $simple_file,
153                            version => '1.23' }});
154
155 {
156   $dist->change_file( 'lib/Simple.pm', <<'---' );
157 package Simple;
158 $VERSION = version->new('0.60.' . (qw$Revision: 128 $)[1]);
159 package Simple::Simon;
160 $VERSION = version->new('0.61.' . (qw$Revision: 129 $)[1]);
161 ---
162   $dist->regen;
163   my $provides = new_build()->prepare_metadata()->{provides};
164   is $provides->{'Simple'}{version}, '0.60.128', "Check version";
165   is $provides->{'Simple::Simon'}{version}, '0.61.129', "Check version";
166   is ref($provides->{'Simple'}{version}), '', "Versions from prepare_metadata() aren't refs";
167   is ref($provides->{'Simple::Simon'}{version}), '', "Versions from prepare_metadata() aren't refs";
168 }
169
170
171 # Single file with multiple differing packages, no corresponding package
172 # Simple.pm => Foo
173 # Simple.pm => Foo::Bar
174
175 $dist->change_file( 'lib/Simple.pm', <<'---' );
176 package Foo;
177 $VERSION = '1.23';
178 package Foo::Bar;
179 $VERSION = '1.23';
180 ---
181 $dist->regen( clean => 1 );
182 $mb = new_build();
183 is_deeply($mb->find_dist_packages,
184           {'Foo'      => { file => $simple_file,
185                            version => '1.23' },
186            'Foo::Bar' => { file => $simple_file,
187                            version => '1.23' }});
188
189
190 # Single file with same package appearing multiple times, no version
191 #   only record a single instance
192 # Simple.pm => Simple
193 # Simple.pm => Simple
194
195 $dist->change_file( 'lib/Simple.pm', <<'---' );
196 package Simple;
197 package Simple;
198 ---
199 $dist->regen( clean => 1 );
200 $mb = new_build();
201 is_deeply($mb->find_dist_packages,
202           {'Simple' => { file => $simple_file }});
203
204
205 # Single file with same package appearing multiple times, single
206 # version 1st package:
207 # Simple.pm => Simple v1.23
208 # Simple.pm => Simple
209
210 $dist->change_file( 'lib/Simple.pm', <<'---' );
211 package Simple;
212 $VERSION = '1.23';
213 package Simple;
214 ---
215 $dist->regen( clean => 1 );
216 $mb = new_build();
217 is_deeply($mb->find_dist_packages,
218           {'Simple' => { file => $simple_file,
219                          version => '1.23' }});
220
221
222 # Single file with same package appearing multiple times, single
223 # version 2nd package
224 # Simple.pm => Simple
225 # Simple.pm => Simple v1.23
226
227 $dist->change_file( 'lib/Simple.pm', <<'---' );
228 package Simple;
229 package Simple;
230 $VERSION = '1.23';
231 ---
232 $dist->regen( clean => 1 );
233 $mb = new_build();
234 is_deeply($mb->find_dist_packages,
235           {'Simple' => { file => $simple_file,
236                          version => '1.23' }});
237
238
239 # Single file with same package appearing multiple times, conflicting versions
240 # Simple.pm => Simple v1.23
241 # Simple.pm => Simple v2.34
242
243 $dist->change_file( 'lib/Simple.pm', <<'---' );
244 package Simple;
245 $VERSION = '1.23';
246 package Simple;
247 $VERSION = '2.34';
248 ---
249 $dist->regen( clean => 1 );
250 my $err = '';
251 $err = stderr_of( sub { $mb = new_build() } );
252 $err = stderr_of( sub { $provides = $mb->find_dist_packages } );
253 is_deeply($provides,
254           {'Simple' => { file => $simple_file,
255                          version => '1.23' }}); # XXX should be 2.34?
256 like( $err, qr/already declared/, '  with conflicting versions reported' );
257
258
259 # (Same as above three cases except with no corresponding package)
260 # Simple.pm => Foo v1.23
261 # Simple.pm => Foo v2.34
262
263 $dist->change_file( 'lib/Simple.pm', <<'---' );
264 package Foo;
265 $VERSION = '1.23';
266 package Foo;
267 $VERSION = '2.34';
268 ---
269 $dist->regen( clean => 1 );
270 $err = stderr_of( sub { $mb = new_build() } );
271 $err = stderr_of( sub { $provides = $mb->find_dist_packages } );
272 is_deeply($provides,
273           {'Foo' => { file => $simple_file,
274                       version => '1.23' }}); # XXX should be 2.34?
275 like( $err, qr/already declared/, '  with conflicting versions reported' );
276
277
278
279 ############################## Multiple Modules
280
281 # Multiple files with same package, no version
282 # Simple.pm  => Simple
283 # Simple2.pm => Simple
284
285 $dist->change_file( 'lib/Simple.pm', <<'---' );
286 package Simple;
287 ---
288 $dist->add_file( 'lib/Simple2.pm', <<'---' );
289 package Simple;
290 ---
291 $dist->regen( clean => 1 );
292 $mb = new_build();
293 is_deeply($mb->find_dist_packages,
294           {'Simple' => { file => $simple_file }});
295 $dist->remove_file( 'lib/Simple2.pm' );
296
297
298 # Multiple files with same package, single version in corresponding package
299 # Simple.pm  => Simple v1.23
300 # Simple2.pm => Simple
301
302 $dist->change_file( 'lib/Simple.pm', <<'---' );
303 package Simple;
304 $VERSION = '1.23';
305 ---
306 $dist->add_file( 'lib/Simple2.pm', <<'---' );
307 package Simple;
308 ---
309 $dist->regen( clean => 1 );
310 $mb = new_build();
311 is_deeply($mb->find_dist_packages,
312           {'Simple' => { file => $simple_file,
313                          version => '1.23' }});
314 $dist->remove_file( 'lib/Simple2.pm' );
315
316
317 # Multiple files with same package,
318 #   single version in non-corresponding package
319 # Simple.pm  => Simple
320 # Simple2.pm => Simple v1.23
321
322 $dist->change_file( 'lib/Simple.pm', <<'---' );
323 package Simple;
324 ---
325 $dist->add_file( 'lib/Simple2.pm', <<'---' );
326 package Simple;
327 $VERSION = '1.23';
328 ---
329 $dist->regen( clean => 1 );
330 $mb = new_build();
331 is_deeply($mb->find_dist_packages,
332           {'Simple' => { file => $simple2_file,
333                          version => '1.23' }});
334 $dist->remove_file( 'lib/Simple2.pm' );
335
336
337 # Multiple files with same package, conflicting versions
338 # Simple.pm  => Simple v1.23
339 # Simple2.pm => Simple v2.34
340
341 $dist->change_file( 'lib/Simple.pm', <<'---' );
342 package Simple;
343 $VERSION = '1.23';
344 ---
345 $dist->add_file( 'lib/Simple2.pm', <<'---' );
346 package Simple;
347 $VERSION = '2.34';
348 ---
349 $dist->regen( clean => 1 );
350 $mb = new_build();
351 $err = stderr_of( sub { $provides = $mb->find_dist_packages } );
352 is_deeply($provides,
353           {'Simple' => { file => $simple_file,
354                          version => '1.23' }});
355 like( $err, qr/Found conflicting versions for package/,
356       '  with conflicting versions reported' );
357 $dist->remove_file( 'lib/Simple2.pm' );
358
359
360 # Multiple files with same package, multiple agreeing versions
361 # Simple.pm  => Simple v1.23
362 # Simple2.pm => Simple v1.23
363
364 $dist->change_file( 'lib/Simple.pm', <<'---' );
365 package Simple;
366 $VERSION = '1.23';
367 ---
368 $dist->add_file( 'lib/Simple2.pm', <<'---' );
369 package Simple;
370 $VERSION = '1.23';
371 ---
372 $dist->regen( clean => 1 );
373 $mb = new_build();
374 $err = stderr_of( sub { $provides = $mb->find_dist_packages } );
375 is_deeply($provides,
376           {'Simple' => { file => $simple_file,
377                          version => '1.23' }});
378 $dist->remove_file( 'lib/Simple2.pm' );
379
380
381 ############################################################
382 #
383 # (Same as above five cases except with non-corresponding package)
384 #
385
386 # Multiple files with same package, no version
387 # Simple.pm  => Foo
388 # Simple2.pm => Foo
389
390 $dist->change_file( 'lib/Simple.pm', <<'---' );
391 package Foo;
392 ---
393 $dist->add_file( 'lib/Simple2.pm', <<'---' );
394 package Foo;
395 ---
396 $dist->regen( clean => 1 );
397 $mb = new_build();
398 $provides = $mb->find_dist_packages;
399 ok( exists( $provides->{Foo} ) ); # it exist, can't predict which file
400 $dist->remove_file( 'lib/Simple2.pm' );
401
402
403 # Multiple files with same package, version in first file
404 # Simple.pm  => Foo v1.23
405 # Simple2.pm => Foo
406
407 $dist->change_file( 'lib/Simple.pm', <<'---' );
408 package Foo;
409 $VERSION = '1.23';
410 ---
411 $dist->add_file( 'lib/Simple2.pm', <<'---' );
412 package Foo;
413 ---
414 $dist->regen( clean => 1 );
415 $mb = new_build();
416 is_deeply($mb->find_dist_packages,
417           {'Foo' => { file => $simple_file,
418                       version => '1.23' }});
419 $dist->remove_file( 'lib/Simple2.pm' );
420
421
422 # Multiple files with same package, version in second file
423 # Simple.pm  => Foo
424 # Simple2.pm => Foo v1.23
425
426 $dist->change_file( 'lib/Simple.pm', <<'---' );
427 package Foo;
428 ---
429 $dist->add_file( 'lib/Simple2.pm', <<'---' );
430 package Foo;
431 $VERSION = '1.23';
432 ---
433 $dist->regen( clean => 1 );
434 $mb = new_build();
435 is_deeply($mb->find_dist_packages,
436           {'Foo' => { file => $simple2_file,
437                       version => '1.23' }});
438 $dist->remove_file( 'lib/Simple2.pm' );
439
440
441 # Multiple files with same package, conflicting versions
442 # Simple.pm  => Foo v1.23
443 # Simple2.pm => Foo v2.34
444
445 $dist->change_file( 'lib/Simple.pm', <<'---' );
446 package Foo;
447 $VERSION = '1.23';
448 ---
449 $dist->add_file( 'lib/Simple2.pm', <<'---' );
450 package Foo;
451 $VERSION = '2.34';
452 ---
453 $dist->regen( clean => 1 );
454 $mb = new_build();
455 $err = stderr_of( sub { $provides = $mb->find_dist_packages } );
456 # XXX Should 'Foo' exist ??? Can't predict values for file & version
457 ok( exists( $provides->{Foo} ) );
458 like( $err, qr/Found conflicting versions for package/,
459       '  with conflicting versions reported' );
460 $dist->remove_file( 'lib/Simple2.pm' );
461
462
463 # Multiple files with same package, multiple agreeing versions
464 # Simple.pm  => Foo v1.23
465 # Simple2.pm => Foo v1.23
466
467 $dist->change_file( 'lib/Simple.pm', <<'---' );
468 package Foo;
469 $VERSION = '1.23';
470 ---
471 $dist->add_file( 'lib/Simple2.pm', <<'---' );
472 package Foo;
473 $VERSION = '1.23';
474 ---
475 $dist->regen( clean => 1 );
476 $mb = new_build();
477 $err = stderr_of( sub { $provides = $mb->find_dist_packages } );
478 ok( exists( $provides->{Foo} ) );
479 is( $provides->{Foo}{version}, '1.23' );
480 ok( exists( $provides->{Foo}{file} ) ); # Can't predict which file
481 is( $err, '', '  no conflicts reported' );
482 $dist->remove_file( 'lib/Simple2.pm' );
483
484 ############################################################
485 # Conflicts among primary & multiple alternatives
486
487 # multiple files, conflicting version in corresponding file
488 $dist->change_file( 'lib/Simple.pm', <<'---' );
489 package Simple;
490 $VERSION = '1.23';
491 ---
492 $dist->add_file( 'lib/Simple2.pm', <<'---' );
493 package Simple;
494 $VERSION = '2.34';
495 ---
496 $dist->add_file( 'lib/Simple3.pm', <<'---' );
497 package Simple;
498 $VERSION = '2.34';
499 ---
500 $dist->regen( clean => 1 );
501 $err = stderr_of( sub {
502   $mb = new_build();
503 } );
504 $err = stderr_of( sub { $provides = $mb->find_dist_packages } );
505 is_deeply($provides,
506           {'Simple' => { file => $simple_file,
507                          version => '1.23' }});
508 like( $err, qr/Found conflicting versions for package/,
509       '  corresponding package conflicts with multiple alternatives' );
510 $dist->remove_file( 'lib/Simple2.pm' );
511 $dist->remove_file( 'lib/Simple3.pm' );
512
513 # multiple files, conflicting version in non-corresponding file
514 $dist->change_file( 'lib/Simple.pm', <<'---' );
515 package Simple;
516 $VERSION = '1.23';
517 ---
518 $dist->add_file( 'lib/Simple2.pm', <<'---' );
519 package Simple;
520 $VERSION = '1.23';
521 ---
522 $dist->add_file( 'lib/Simple3.pm', <<'---' );
523 package Simple;
524 $VERSION = '2.34';
525 ---
526 $dist->regen( clean => 1 );
527 $err = stderr_of( sub {
528   $mb = new_build();
529 } );
530 $err = stderr_of( sub { $provides = $mb->find_dist_packages } );
531 is_deeply($provides,
532           {'Simple' => { file => $simple_file,
533                          version => '1.23' }});
534 like( $err, qr/Found conflicting versions for package/,
535       '  only one alternative conflicts with corresponding package' );
536 $dist->remove_file( 'lib/Simple2.pm' );
537 $dist->remove_file( 'lib/Simple3.pm' );
538
539
540 ############################################################
541 # Don't record private packages (beginning with underscore)
542 # Simple.pm => Simple::_private
543 # Simple.pm => Simple::_private::too
544
545 $dist->change_file( 'lib/Simple.pm', <<'---' );
546 package Simple;
547 $VERSION = '1.23';
548 package Simple::_private;
549 $VERSION = '2.34';
550 package Simple::_private::too;
551 $VERSION = '3.45';
552 ---
553 $dist->regen( clean => 1 );
554 $mb = new_build();
555 is_deeply($mb->find_dist_packages,
556           {'Simple' => { file => $simple_file,
557                          version => '1.23' }});
558
559
560 ############################################################
561 # Files with no packages?
562
563 # Simple.pm => <empty>
564
565 $dist->change_file( 'lib/Simple.pm', '' );
566 $dist->regen( clean => 1 );
567 $mb = new_build();
568 is_deeply( $mb->find_dist_packages, {} );
569
570 # Simple.pm => =pod..=cut (no package declaration)
571 $dist->change_file( 'lib/Simple.pm', <<'---' );
572 =pod
573
574 =head1 NAME
575
576 Simple - Pure Documentation
577
578 =head1 DESCRIPTION
579
580 Doesn't do anything.
581
582 =cut
583 ---
584 $dist->regen( clean => 1 );
585 $mb = new_build();
586 is_deeply($mb->find_dist_packages, {});
587
588 ############################################################
589 # cleanup
590 chdir( $cwd ) or die "Can't chdir to '$cwd': $!";
591 $dist->remove;
592
593 use File::Path;
594 rmtree( $tmp );