This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
ca928631e9f35c5a3a8ca35ebdd558ba6ae6be6b
[perl5.git] / cpan / Module-Metadata / t / metadata.t
1 #!/usr/bin/perl -w
2 # -*- mode: cperl; tab-width: 8; indent-tabs-mode: nil; basic-offset: 2 -*-
3 # vim:ts=8:sw=2:et:sta:sts=2
4
5 use strict;
6 use warnings;
7 use Test::More 0.82;
8 use IO::File;
9 use File::Spec;
10 use File::Temp;
11 use File::Basename;
12 use Cwd ();
13 use File::Path;
14 use Data::Dumper;
15
16 my $undef;
17
18 # parse various module $VERSION lines
19 # format: expected version => code snippet
20 my @modules = (
21   $undef => <<'---', # no $VERSION line
22 package Simple;
23 ---
24   $undef => <<'---', # undefined $VERSION
25 package Simple;
26 our $VERSION;
27 ---
28   '1.23' => <<'---', # declared & defined on same line with 'our'
29 package Simple;
30 our $VERSION = '1.23';
31 ---
32   '1.23' => <<'---', # declared & defined on separate lines with 'our'
33 package Simple;
34 our $VERSION;
35 $VERSION = '1.23';
36 ---
37   '1.23' => <<'---', # commented & defined on same line
38 package Simple;
39 our $VERSION = '1.23'; # our $VERSION = '4.56';
40 ---
41   '1.23' => <<'---', # commented & defined on separate lines
42 package Simple;
43 # our $VERSION = '4.56';
44 our $VERSION = '1.23';
45 ---
46   '1.23' => <<'---', # use vars
47 package Simple;
48 use vars qw( $VERSION );
49 $VERSION = '1.23';
50 ---
51   '1.23' => <<'---', # choose the right default package based on package/file name
52 package Simple::_private;
53 $VERSION = '0';
54 package Simple;
55 $VERSION = '1.23'; # this should be chosen for version
56 ---
57   '1.23' => <<'---', # just read the first $VERSION line
58 package Simple;
59 $VERSION = '1.23'; # we should see this line
60 $VERSION = eval $VERSION; # and ignore this one
61 ---
62   '1.23' => <<'---', # just read the first $VERSION line in reopened package (1)
63 package Simple;
64 $VERSION = '1.23';
65 package Error::Simple;
66 $VERSION = '2.34';
67 package Simple;
68 ---
69   '1.23' => <<'---', # just read the first $VERSION line in reopened package (2)
70 package Simple;
71 package Error::Simple;
72 $VERSION = '2.34';
73 package Simple;
74 $VERSION = '1.23';
75 ---
76   '1.23' => <<'---', # mentions another module's $VERSION
77 package Simple;
78 $VERSION = '1.23';
79 if ( $Other::VERSION ) {
80     # whatever
81 }
82 ---
83   '1.23' => <<'---', # mentions another module's $VERSION in a different package
84 package Simple;
85 $VERSION = '1.23';
86 package Simple2;
87 if ( $Simple::VERSION ) {
88     # whatever
89 }
90 ---
91   '1.23' => <<'---', # $VERSION checked only in assignments, not regexp ops
92 package Simple;
93 $VERSION = '1.23';
94 if ( $VERSION =~ /1\.23/ ) {
95     # whatever
96 }
97 ---
98   '1.23' => <<'---', # $VERSION checked only in assignments, not relational ops
99 package Simple;
100 $VERSION = '1.23';
101 if ( $VERSION == 3.45 ) {
102     # whatever
103 }
104 ---
105   '1.23' => <<'---', # $VERSION checked only in assignments, not relational ops
106 package Simple;
107 $VERSION = '1.23';
108 package Simple2;
109 if ( $Simple::VERSION == 3.45 ) {
110     # whatever
111 }
112 ---
113   '1.23' => <<'---', # Fully qualified $VERSION declared in package
114 package Simple;
115 $Simple::VERSION = 1.23;
116 ---
117   '1.23' => <<'---', # Differentiate fully qualified $VERSION in a package
118 package Simple;
119 $Simple2::VERSION = '999';
120 $Simple::VERSION = 1.23;
121 ---
122   '1.23' => <<'---', # Differentiate fully qualified $VERSION and unqualified
123 package Simple;
124 $Simple2::VERSION = '999';
125 $VERSION = 1.23;
126 ---
127   '1.23' => <<'---', # $VERSION declared as package variable from within 'main' package
128 $Simple::VERSION = '1.23';
129 {
130   package Simple;
131   $x = $y, $cats = $dogs;
132 }
133 ---
134   '1.23' => <<'---', # $VERSION wrapped in parens - space inside
135 package Simple;
136 ( $VERSION ) = '1.23';
137 ---
138   '1.23' => <<'---', # $VERSION wrapped in parens - no space inside
139 package Simple;
140 ($VERSION) = '1.23';
141 ---
142   '1.23' => <<'---', # $VERSION follows a spurious 'package' in a quoted construct
143 package Simple;
144 __PACKAGE__->mk_accessors(qw(
145     program socket proc
146     package filename line codeline subroutine finished));
147
148 our $VERSION = "1.23";
149 ---
150   '1.23' => <<'---', # $VERSION using version.pm
151   package Simple;
152   use version; our $VERSION = version->new('1.23');
153 ---
154   'v1.230' => <<'---', # $VERSION using version.pm and qv()
155   package Simple;
156   use version; our $VERSION = qv('1.230');
157 ---
158   '1.230' => <<'---', # Two version assignments, should ignore second one
159   $Simple::VERSION = '1.230';
160   $Simple::VERSION = eval $Simple::VERSION;
161 ---
162   '1.230000' => <<'---', # declared & defined on same line with 'our'
163 package Simple;
164 our $VERSION = '1.23_00_00';
165 ---
166   '1.23' => <<'---', # package NAME VERSION
167   package Simple 1.23;
168 ---
169   '1.23_01' => <<'---', # package NAME VERSION
170   package Simple 1.23_01;
171 ---
172   'v1.2.3' => <<'---', # package NAME VERSION
173   package Simple v1.2.3;
174 ---
175   'v1.2_3' => <<'---', # package NAME VERSION
176   package Simple v1.2_3;
177 ---
178   '1.23' => <<'---', # trailing crud
179   package Simple;
180   our $VERSION;
181   $VERSION = '1.23-alpha';
182 ---
183   '1.23' => <<'---', # trailing crud
184   package Simple;
185   our $VERSION;
186   $VERSION = '1.23b';
187 ---
188   '1.234' => <<'---', # multi_underscore
189   package Simple;
190   our $VERSION;
191   $VERSION = '1.2_3_4';
192 ---
193   '0' => <<'---', # non-numeric
194   package Simple;
195   our $VERSION;
196   $VERSION = 'onetwothree';
197 ---
198   $undef => <<'---', # package NAME BLOCK, undef $VERSION
199 package Simple {
200   our $VERSION;
201 }
202 ---
203   '1.23' => <<'---', # package NAME BLOCK, with $VERSION
204 package Simple {
205   our $VERSION = '1.23';
206 }
207 ---
208   '1.23' => <<'---', # package NAME VERSION BLOCK
209 package Simple 1.23 {
210   1;
211 }
212 ---
213   'v1.2.3_4' => <<'---', # package NAME VERSION BLOCK
214 package Simple v1.2.3_4 {
215   1;
216 }
217 ---
218   '0' => <<'---', # set from separately-initialised variable
219 package Simple;
220   our $CVSVERSION   = '$Revision: 1.7 $';
221   our ($VERSION)    = ($CVSVERSION =~ /(\d+\.\d+)/);
222 }
223 ---
224   'v2.2.102.2' => <<'---', # our + bare v-string
225 package Simple;
226 our $VERSION     = v2.2.102.2;
227 ---
228   '0.0.9_1' => <<'---', # our + dev release
229 package Simple;
230 our $VERSION = "0.0.9_1";
231 ---
232   '1.12' => <<'---', # our + crazy string and substitution code
233 package Simple;
234 our $VERSION     = '1.12.B55J2qn'; our $WTF = $VERSION; $WTF =~ s/^\d+\.\d+\.//; # attempts to rationalize $WTF go here.
235 ---
236   '1.12' => <<'---', # our in braces, as in Dist::Zilla::Plugin::PkgVersion with use_our = 1
237 package Simple;
238 { our $VERSION = '1.12'; }
239 ---
240   sub { defined $_[0] and $_[0] =~ /^3\.14159/ } => <<'---', # calculated version - from Acme-Pi-3.14
241 package Simple;
242 my $version = atan2(1,1) * 4; $Simple::VERSION = "$version";
243 1;
244 ---
245 );
246
247 # format: expected package name => code snippet
248 my @pkg_names = (
249   [ 'Simple' ] => <<'---', # package NAME
250 package Simple;
251 ---
252   [ 'Simple::Edward' ] => <<'---', # package NAME::SUBNAME
253 package Simple::Edward;
254 ---
255   [ 'Simple::Edward::' ] => <<'---', # package NAME::SUBNAME::
256 package Simple::Edward::;
257 ---
258   [ "Simple'Edward" ] => <<'---', # package NAME'SUBNAME
259 package Simple'Edward;
260 ---
261   [ "Simple'Edward::" ] => <<'---', # package NAME'SUBNAME::
262 package Simple'Edward::;
263 ---
264   [ 'Simple::::Edward' ] => <<'---', # package NAME::::SUBNAME
265 package Simple::::Edward;
266 ---
267   [ '::Simple::Edward' ] => <<'---', # package ::NAME::SUBNAME
268 package ::Simple::Edward;
269 ---
270   [ 'main' ] => <<'---', # package NAME:SUBNAME (fail)
271 package Simple:Edward;
272 ---
273   [ 'main' ] => <<'---', # package NAME' (fail)
274 package Simple';
275 ---
276   [ 'main' ] => <<'---', # package NAME::SUBNAME' (fail)
277 package Simple::Edward';
278 ---
279   [ 'main' ] => <<'---', # package NAME''SUBNAME (fail)
280 package Simple''Edward;
281 ---
282   [ 'main' ] => <<'---', # package NAME-SUBNAME (fail)
283 package Simple-Edward;
284 ---
285 );
286
287 # 2 tests per each pair of @modules (plus 1 for defined keys), 2 per pair of @pkg_names
288 plan tests => 63
289   + ( @modules + grep { defined $modules[2*$_] } 0..$#modules/2 )
290   + ( @pkg_names );
291
292 require_ok('Module::Metadata');
293
294 {
295     # class method C<find_module_by_name>
296     my $module = Module::Metadata->find_module_by_name(
297                    'Module::Metadata' );
298     ok( -e $module, 'find_module_by_name() succeeds' );
299 }
300
301 #########################
302
303 BEGIN {
304   my $cwd = File::Spec->rel2abs(Cwd::cwd);
305   sub original_cwd { return $cwd }
306 }
307
308 # Set up a temp directory
309 sub tmpdir {
310   my (@args) = @_;
311   my $dir = $ENV{PERL_CORE} ? original_cwd : File::Spec->tmpdir;
312   return File::Temp::tempdir('MMD-XXXXXXXX', CLEANUP => 0, DIR => $dir, @args);
313 }
314
315 my $tmp;
316 BEGIN { $tmp = tmpdir; note "using temp dir $tmp"; }
317
318 END {
319   die "tests failed; leaving temp dir $tmp behind"
320     if $ENV{AUTHOR_TESTING} and not Test::Builder->new->is_passing;
321   note "removing temp dir $tmp";
322   chdir original_cwd;
323   File::Path::rmtree($tmp);
324 }
325
326 # generates a new distribution:
327 # files => { relative filename => $content ... }
328 # returns the name of the distribution (not including version),
329 # and the absolute path name to the dist.
330 {
331   my $test_num = 0;
332   sub new_dist {
333     my %opts = @_;
334
335     my $distname = 'Simple' . $test_num++;
336     my $distdir = File::Spec->catdir($tmp, $distname);
337     note "using dist $distname in $distdir";
338
339     File::Path::mkpath($distdir) or die "failed to create '$distdir'";
340
341     foreach my $rel_filename (keys %{$opts{files}})
342     {
343       my $abs_filename = File::Spec->catfile($distdir, $rel_filename);
344       my $dirname = File::Basename::dirname($abs_filename);
345       unless (-d $dirname) {
346         File::Path::mkpath($dirname) or die "Can't create '$dirname'";
347       }
348
349       note "creating $abs_filename";
350       my $fh = IO::File->new(">$abs_filename") or die "Can't write '$abs_filename'\n";
351       print $fh $opts{files}{$rel_filename};
352       close $fh;
353     }
354
355     chdir $distdir;
356     return ($distname, $distdir);
357   }
358 }
359
360 {
361   # fail on invalid module name
362   my $pm_info = Module::Metadata->new_from_module(
363                   'Foo::Bar', inc => [] );
364   ok( !defined( $pm_info ), 'fail if can\'t find module by module name' );
365 }
366
367 {
368   # fail on invalid filename
369   my $file = File::Spec->catfile( 'Foo', 'Bar.pm' );
370   my $pm_info = Module::Metadata->new_from_file( $file, inc => [] );
371   ok( !defined( $pm_info ), 'fail if can\'t find module by file name' );
372 }
373
374 {
375   my $file = File::Spec->catfile('lib', 'Simple.pm');
376   my ($dist_name, $dist_dir) = new_dist(files => { $file => "package Simple;\n" });
377
378   # construct from module filename
379   my $pm_info = Module::Metadata->new_from_file( $file );
380   ok( defined( $pm_info ), 'new_from_file() succeeds' );
381
382   # construct from filehandle
383   my $handle = IO::File->new($file);
384   $pm_info = Module::Metadata->new_from_handle( $handle, $file );
385   ok( defined( $pm_info ), 'new_from_handle() succeeds' );
386   $pm_info = Module::Metadata->new_from_handle( $handle );
387   is( $pm_info, undef, "new_from_handle() without filename returns undef" );
388   close($handle);
389 }
390
391 {
392   # construct from module name, using custom include path
393   my $pm_info = Module::Metadata->new_from_module(
394                'Simple', inc => [ 'lib', @INC ] );
395   ok( defined( $pm_info ), 'new_from_module() succeeds' );
396 }
397
398
399 # iterate through @modules pairwise
400 my $test_case = 0;
401 while (++$test_case and my ($expected_version, $code) = splice @modules, 0, 2 ) {
402  SKIP: {
403     skip( "No our() support until perl 5.6", (defined $expected_version ? 3 : 2) )
404         if $] < 5.006 && $code =~ /\bour\b/;
405     skip( "No package NAME VERSION support until perl 5.11.1", (defined $expected_version ? 3 : 2) )
406         if $] < 5.011001 && $code =~ /package\s+[\w\:\']+\s+v?[0-9._]+/;
407
408     my $file = File::Spec->catfile('lib', 'Simple.pm');
409     my ($dist_name, $dist_dir) = new_dist(files => { $file => $code });
410
411     my $warnings = '';
412     local $SIG{__WARN__} = sub { $warnings .= $_ for @_ };
413     my $pm_info = Module::Metadata->new_from_file( $file );
414
415     my $errs;
416     my $got = $pm_info->version;
417
418     # note that in Test::More 0.94 and earlier, is() stringifies first before comparing;
419     # from 0.95_01 and later, it just lets the objects figure out how to handle 'eq'
420     # We want to ensure we preserve the original, as long as it's legal, so we
421     # explicitly check the stringified form.
422     isa_ok($got, 'version') if defined $expected_version;
423
424     if (ref($expected_version) eq 'CODE') {
425       ok(
426         $expected_version->($got),
427         "case $test_case: module version passes match sub"
428       )
429       or $errs++;
430     }
431     else {
432       is(
433         (defined $got ? "$got" : $got),
434         $expected_version,
435         "case $test_case: correct module version ("
436           . (defined $expected_version? "'$expected_version'" : 'undef')
437           . ')'
438       )
439       or $errs++;
440     }
441
442     is( $warnings, '', "case $test_case: no warnings from parsing" ) or $errs++;
443     diag Dumper({ got => $pm_info->version, module_contents => $code }) if $errs;
444   }
445 }
446
447 $test_case = 0;
448 while (++$test_case and my ($expected_name, $code) = splice @pkg_names, 0, 2) {
449     my $file = File::Spec->catfile('lib', 'Simple.pm');
450     my ($dist_name, $dist_dir) = new_dist(files => { $file => $code });
451
452     my $warnings = '';
453     local $SIG{__WARN__} = sub { $warnings .= $_ for @_ };
454     my $pm_info = Module::Metadata->new_from_file( $file );
455
456     # Test::Builder will prematurely numify objects, so use this form
457     my $errs;
458     my @got = $pm_info->packages_inside();
459     is_deeply( \@got, $expected_name,
460                "case $test_case: correct package names (expected '" . join(', ', @$expected_name) . "')" )
461             or $errs++;
462     is( $warnings, '', "case $test_case: no warnings from parsing" ) or $errs++;
463     diag "Got: '" . join(', ', @got) . "'\nModule contents:\n$code" if $errs;
464 }
465
466 {
467   # Find each package only once
468   my $file = File::Spec->catfile('lib', 'Simple.pm');
469   my ($dist_name, $dist_dir) = new_dist(files => { $file => <<'---' } );
470 package Simple;
471 $VERSION = '1.23';
472 package Error::Simple;
473 $VERSION = '2.34';
474 package Simple;
475 ---
476
477   my $pm_info = Module::Metadata->new_from_file( $file );
478
479   my @packages = $pm_info->packages_inside;
480   is( @packages, 2, 'record only one occurence of each package' );
481 }
482
483 {
484   # Module 'Simple.pm' does not contain package 'Simple';
485   # constructor should not complain, no default module name or version
486   my $file = File::Spec->catfile('lib', 'Simple.pm');
487   my ($dist_name, $dist_dir) = new_dist(files => { $file => <<'---' } );
488 package Simple::Not;
489 $VERSION = '1.23';
490 ---
491
492   my $pm_info = Module::Metadata->new_from_file( $file );
493
494   is( $pm_info->name, undef, 'no default package' );
495   is( $pm_info->version, undef, 'no version w/o default package' );
496 }
497
498 {
499   # Module 'Simple.pm' contains an alpha version
500   # constructor should report first $VERSION found
501   my $file = File::Spec->catfile('lib', 'Simple.pm');
502   my ($dist_name, $dist_dir) = new_dist(files => { $file => <<'---' } );
503 package Simple;
504 $VERSION = '1.23_01';
505 $VERSION = eval $VERSION;
506 ---
507
508   my $pm_info = Module::Metadata->new_from_file( $file );
509
510   is( $pm_info->version, '1.23_01', 'alpha version reported');
511
512   # NOTE the following test has be done this way because Test::Builder is
513   # too smart for our own good and tries to see if the version object is a
514   # dual-var, which breaks with alpha versions:
515   #    Argument "1.23_0100" isn't numeric in addition (+) at
516   #    /usr/lib/perl5/5.8.7/Test/Builder.pm line 505.
517
518   ok( $pm_info->version > 1.23, 'alpha version greater than non');
519 }
520
521 # parse $VERSION lines scripts for package main
522 my @scripts = (
523   <<'---', # package main declared
524 #!perl -w
525 package main;
526 $VERSION = '0.01';
527 ---
528   <<'---', # on first non-comment line, non declared package main
529 #!perl -w
530 $VERSION = '0.01';
531 ---
532   <<'---', # after non-comment line
533 #!perl -w
534 use strict;
535 $VERSION = '0.01';
536 ---
537   <<'---', # 1st declared package
538 #!perl -w
539 package main;
540 $VERSION = '0.01';
541 package _private;
542 $VERSION = '999';
543 ---
544   <<'---', # 2nd declared package
545 #!perl -w
546 package _private;
547 $VERSION = '999';
548 package main;
549 $VERSION = '0.01';
550 ---
551   <<'---', # split package
552 #!perl -w
553 package main;
554 package _private;
555 $VERSION = '999';
556 package main;
557 $VERSION = '0.01';
558 ---
559   <<'---', # define 'main' version from other package
560 package _private;
561 $::VERSION = 0.01;
562 $VERSION = '999';
563 ---
564   <<'---', # define 'main' version from other package
565 package _private;
566 $VERSION = '999';
567 $::VERSION = 0.01;
568 ---
569 );
570
571 my ( $i, $n ) = ( 1, scalar( @scripts ) );
572 foreach my $script ( @scripts ) {
573   my $file = File::Spec->catfile('bin', 'simple.plx');
574   my ($dist_name, $dist_dir) = new_dist(files => { $file => $script } );
575   my $pm_info = Module::Metadata->new_from_file( $file );
576
577   is( $pm_info->version, '0.01', "correct script version ($i of $n)" );
578   $i++;
579 }
580
581 {
582   # examine properties of a module: name, pod, etc
583   my $file = File::Spec->catfile('lib', 'Simple.pm');
584   my ($dist_name, $dist_dir) = new_dist(files => { $file => <<'---' } );
585 package Simple;
586 $VERSION = '0.01';
587 package Simple::Ex;
588 $VERSION = '0.02';
589
590 =head1 NAME
591
592 Simple - It's easy.
593
594 =head1 AUTHOR
595
596 Simple Simon
597
598 You can find me on the IRC channel
599 #simon on irc.perl.org.
600
601 =cut
602 ---
603
604   my $pm_info = Module::Metadata->new_from_module(
605              'Simple', inc => [ 'lib', @INC ] );
606
607   is( $pm_info->name, 'Simple', 'found default package' );
608   is( $pm_info->version, '0.01', 'version for default package' );
609
610   # got correct version for secondary package
611   is( $pm_info->version( 'Simple::Ex' ), '0.02',
612       'version for secondary package' );
613
614   my $filename = $pm_info->filename;
615   ok( defined( $filename ) && -e $filename,
616       'filename() returns valid path to module file' );
617
618   my @packages = $pm_info->packages_inside;
619   is( @packages, 2, 'found correct number of packages' );
620   is( $packages[0], 'Simple', 'packages stored in order found' );
621
622   # we can detect presence of pod regardless of whether we are collecting it
623   ok( $pm_info->contains_pod, 'contains_pod() succeeds' );
624
625   my @pod = $pm_info->pod_inside;
626   is_deeply( \@pod, [qw(NAME AUTHOR)], 'found all pod sections' );
627
628   is( $pm_info->pod('NONE') , undef,
629       'return undef() if pod section not present' );
630
631   is( $pm_info->pod('NAME'), undef,
632       'return undef() if pod section not collected' );
633
634
635   # collect_pod
636   $pm_info = Module::Metadata->new_from_module(
637                'Simple', inc => [ 'lib', @INC ], collect_pod => 1 );
638
639   my %pod;
640   for my $section (qw(NAME AUTHOR)) {
641     my $content = $pm_info->pod( $section );
642     if ( $content ) {
643       $content =~ s/^\s+//;
644       $content =~ s/\s+$//;
645     }
646     $pod{$section} = $content;
647   }
648   my %expected = (
649     NAME   => q|Simple - It's easy.|,
650     AUTHOR => <<'EXPECTED'
651 Simple Simon
652
653 You can find me on the IRC channel
654 #simon on irc.perl.org.
655 EXPECTED
656   );
657   for my $text (values %expected) {
658     $text =~ s/^\s+//;
659     $text =~ s/\s+$//;
660   }
661   is( $pod{NAME},   $expected{NAME},   'collected NAME pod section' );
662   is( $pod{AUTHOR}, $expected{AUTHOR}, 'collected AUTHOR pod section' );
663 }
664
665 {
666   # test things that look like POD, but aren't
667   my $file = File::Spec->catfile('lib', 'Simple.pm');
668   my ($dist_name, $dist_dir) = new_dist(files => { $file => <<'---' } );
669 package Simple;
670
671 =YES THIS STARTS POD
672
673 our $VERSION = '999';
674
675 =cute
676
677 our $VERSION = '666';
678
679 =cut
680
681 *foo
682 =*no_this_does_not_start_pod;
683
684 our $VERSION = '1.23';
685
686 ---
687   my $pm_info = Module::Metadata->new_from_file('lib/Simple.pm');
688   is( $pm_info->name, 'Simple', 'found default package' );
689   is( $pm_info->version, '1.23', 'version for default package' );
690 }
691
692 {
693   # Make sure processing stops after __DATA__
694   my $file = File::Spec->catfile('lib', 'Simple.pm');
695   my ($dist_name, $dist_dir) = new_dist(files => { $file => <<'---' } );
696 package Simple;
697 $VERSION = '0.01';
698 __DATA__
699 *UNIVERSAL::VERSION = sub {
700   foo();
701 };
702 ---
703
704   my $pm_info = Module::Metadata->new_from_file('lib/Simple.pm');
705   is( $pm_info->name, 'Simple', 'found default package' );
706   is( $pm_info->version, '0.01', 'version for default package' );
707   my @packages = $pm_info->packages_inside;
708   is_deeply(\@packages, ['Simple'], 'packages inside');
709 }
710
711 {
712   # Make sure we handle version.pm $VERSIONs well
713   my $file = File::Spec->catfile('lib', 'Simple.pm');
714   my ($dist_name, $dist_dir) = new_dist(files => { $file => <<'---' } );
715 package Simple;
716 $VERSION = version->new('0.60.' . (qw$Revision: 128 $)[1]);
717 package Simple::Simon;
718 $VERSION = version->new('0.61.' . (qw$Revision: 129 $)[1]);
719 ---
720
721   my $pm_info = Module::Metadata->new_from_file('lib/Simple.pm');
722   is( $pm_info->name, 'Simple', 'found default package' );
723   is( $pm_info->version, '0.60.128', 'version for default package' );
724   my @packages = $pm_info->packages_inside;
725   is_deeply([sort @packages], ['Simple', 'Simple::Simon'], 'packages inside');
726   is( $pm_info->version('Simple::Simon'), '0.61.129', 'version for embedded package' );
727 }
728
729 # check that package_versions_from_directory works
730
731 {
732   my $file = File::Spec->catfile('lib', 'Simple.pm');
733   my ($dist_name, $dist_dir) = new_dist(files => { $file => <<'---' } );
734 package Simple;
735 $VERSION = '0.01';
736 package Simple::Ex;
737 $VERSION = '0.02';
738 {
739   package main; # should ignore this
740 }
741 {
742   package DB; # should ignore this
743 }
744 {
745   package Simple::_private; # should ignore this
746 }
747
748 =head1 NAME
749
750 Simple - It's easy.
751
752 =head1 AUTHOR
753
754 Simple Simon
755
756 =cut
757 ---
758
759   my $exp_pvfd = {
760     'Simple' => {
761       'file' => 'Simple.pm',
762       'version' => '0.01'
763     },
764     'Simple::Ex' => {
765       'file' => 'Simple.pm',
766       'version' => '0.02'
767     }
768   };
769
770   my $got_pvfd = Module::Metadata->package_versions_from_directory('lib');
771
772   is_deeply( $got_pvfd, $exp_pvfd, "package_version_from_directory()" )
773     or diag explain $got_pvfd;
774
775 {
776   my $got_provides = Module::Metadata->provides(dir => 'lib', version => 2);
777   my $exp_provides = {
778     'Simple' => {
779       'file' => 'lib/Simple.pm',
780       'version' => '0.01'
781     },
782     'Simple::Ex' => {
783       'file' => 'lib/Simple.pm',
784       'version' => '0.02'
785     }
786   };
787
788   is_deeply( $got_provides, $exp_provides, "provides()" )
789     or diag explain $got_provides;
790 }
791
792 {
793   my $got_provides = Module::Metadata->provides(dir => 'lib', prefix => 'other', version => 1.4);
794   my $exp_provides = {
795     'Simple' => {
796       'file' => 'other/Simple.pm',
797       'version' => '0.01'
798     },
799     'Simple::Ex' => {
800       'file' => 'other/Simple.pm',
801       'version' => '0.02'
802     }
803   };
804
805   is_deeply( $got_provides, $exp_provides, "provides()" )
806     or diag explain $got_provides;
807 }
808 }
809
810 # Check package_versions_from_directory with regard to case-sensitivity
811 {
812   my $file = File::Spec->catfile('lib', 'Simple.pm');
813   my ($dist_name, $dist_dir) = new_dist(files => { $file => <<'---' } );
814 package simple;
815 $VERSION = '0.01';
816 ---
817
818   my $pm_info = Module::Metadata->new_from_file('lib/Simple.pm');
819   is( $pm_info->name, undef, 'no default package' );
820   is( $pm_info->version, undef, 'version for default package' );
821   is( $pm_info->version('simple'), '0.01', 'version for lower-case package' );
822   is( $pm_info->version('Simple'), undef, 'version for capitalized package' );
823   ok( $pm_info->is_indexable(), 'an indexable package is found' );
824   ok( $pm_info->is_indexable('simple'), 'the simple package is indexable' );
825   ok( !$pm_info->is_indexable('Simple'), 'the Simple package would not be indexed' );
826 }
827
828 {
829   my $file = File::Spec->catfile('lib', 'Simple.pm');
830   my ($dist_name, $dist_dir) = new_dist(files => { $file => <<'---' } );
831 package simple;
832 $VERSION = '0.01';
833 package Simple;
834 $VERSION = '0.02';
835 package SiMpLe;
836 $VERSION = '0.03';
837 ---
838
839   my $pm_info = Module::Metadata->new_from_file('lib/Simple.pm');
840   is( $pm_info->name, 'Simple', 'found default package' );
841   is( $pm_info->version, '0.02', 'version for default package' );
842   is( $pm_info->version('simple'), '0.01', 'version for lower-case package' );
843   is( $pm_info->version('Simple'), '0.02', 'version for capitalized package' );
844   is( $pm_info->version('SiMpLe'), '0.03', 'version for mixed-case package' );
845   ok( $pm_info->is_indexable('simple'), 'the simple package is indexable' );
846   ok( $pm_info->is_indexable('Simple'), 'the Simple package is indexable' );
847 }
848
849 {
850   my $file = File::Spec->catfile('lib', 'Simple.pm');
851   my ($dist_name, $dist_dir) = new_dist(files => { $file => <<'---' } );
852 package ## hide from PAUSE
853    simple;
854 $VERSION = '0.01';
855 ---
856
857   my $pm_info = Module::Metadata->new_from_file('lib/Simple.pm');
858   is( $pm_info->name, undef, 'no package names found' );
859   ok( !$pm_info->is_indexable('simple'), 'the simple package would not be indexed' );
860   ok( !$pm_info->is_indexable('Simple'), 'the Simple package would not be indexed' );
861   ok( !$pm_info->is_indexable(), 'no indexable package is found' );
862 }