1use strict; 2use warnings; 3# vim:ts=8:sw=2:et:sta:sts=2 4 5use Test::More 0.88; 6use Module::Metadata; 7 8use lib 't/lib'; 9use GeneratePackage; 10 11# parse package names 12# format: { 13# name => test name 14# code => code snippet (string) 15# package => expected package names 16# } 17my @pkg_names = ( 18{ 19 name => 'package NAME', 20 package => [ 'Simple' ], 21 code => <<'---', 22package Simple; 23--- 24}, 25{ 26 name => 'package NAME::SUBNAME', 27 package => [ 'Simple::Edward' ], 28 code => <<'---', 29package Simple::Edward; 30--- 31}, 32{ 33 name => 'package NAME::SUBNAME::', 34 package => [ 'Simple::Edward::' ], 35 code => <<'---', 36package Simple::Edward::; 37--- 38}, 39{ 40 name => "package NAME'SUBNAME", 41 package => [ "Simple'Edward" ], 42 code => <<'---', 43package Simple'Edward; 44--- 45}, 46{ 47 name => "package NAME'SUBNAME::", 48 package => [ "Simple'Edward::" ], 49 code => <<'---', 50package Simple'Edward::; 51--- 52}, 53{ 54 name => 'package NAME::::SUBNAME', 55 package => [ 'Simple::::Edward' ], 56 code => <<'---', 57package Simple::::Edward; 58--- 59}, 60{ 61 name => 'package ::NAME::SUBNAME', 62 package => [ '::Simple::Edward' ], 63 code => <<'---', 64package ::Simple::Edward; 65--- 66}, 67{ 68 name => 'package NAME:SUBNAME (fail)', 69 package => [ 'main' ], 70 code => <<'---', 71package Simple:Edward; 72--- 73}, 74{ 75 name => "package NAME' (fail)", 76 package => [ 'main' ], 77 code => <<'---', 78package Simple'; 79--- 80}, 81{ 82 name => "package NAME::SUBNAME' (fail)", 83 package => [ 'main' ], 84 code => <<'---', 85package Simple::Edward'; 86--- 87}, 88{ 89 name => "package NAME''SUBNAME (fail)", 90 package => [ 'main' ], 91 code => <<'---', 92package Simple''Edward; 93--- 94}, 95{ 96 name => 'package NAME-SUBNAME (fail)', 97 package => [ 'main' ], 98 code => <<'---', 99package Simple-Edward; 100--- 101}, 102{ 103 name => 'no assumption of package merely if its $VERSION is referenced', 104 package => [ 'Simple' ], 105 code => <<'---', 106package Simple; 107$Foo::Bar::VERSION = '1.23'; 108--- 109}, 110{ 111 name => 'script 7 from t/metadata.t', # TODO merge these 112 package => [ '_private', 'main' ], 113 TODO => '$::VERSION indicates main namespace is referenced', 114 code => <<'---', 115package _private; 116$::VERSION = 0.01; 117$VERSION = '999'; 118--- 119}, 120{ 121 name => 'script 8 from t/metadata.t', # TODO merge these 122 package => [ '_private', 'main' ], 123 TODO => '$::VERSION indicates main namespace is referenced', 124 code => <<'---', 125package _private; 126$VERSION = '999'; 127$::VERSION = 0.01; 128--- 129}, 130); 131 132my $test_num = 0; 133 134my $tmpdir = GeneratePackage::tmpdir(); 135 136foreach my $test_case (@pkg_names) { 137 note '-------'; 138 note $test_case->{name}; 139 my $code = $test_case->{code}; 140 my $expected_name = $test_case->{package}; 141 142 my $warnings = ''; 143 local $SIG{__WARN__} = sub { $warnings .= $_ for @_ }; 144 145 my $pm_info = Module::Metadata->new_from_file(generate_file(File::Spec->catfile($tmpdir, "Simple${test_num}"), 'Simple.pm', $code)); 146 147 # whenever we drop support for 5.6, we can do this: 148 # open my $fh, '<', \(encode('UTF-8', $code, Encode::FB_CROAK)) 149 # or die "cannot open handle to code string: $!"; 150 # my $pm_info = Module::Metadata->new_from_handle($fh, 'lib/Simple.pm'); 151 152 # Test::Builder will prematurely numify objects, so use this form 153 my $errs; 154 my @got = $pm_info->packages_inside(); 155 { 156 local $TODO = $test_case->{TODO}; 157 is_deeply( \@got, $expected_name, 158 "case $test_case->{name}: correct package names (expected '" . join(', ', @$expected_name) . "')" ) 159 or $errs++; 160 } 161 is( $warnings, '', "case $test_case->{name}: no warnings from parsing" ) or $errs++; 162 diag "Got: '" . join(', ', @got) . "'\nModule contents:\n$code" 163 if $errs and not $ENV{PERL_CORE} and ($ENV{AUTHOR_TESTING} or $ENV{AUTOMATED_TESTING}); 164} 165continue { 166 ++$test_num; 167} 168 169done_testing; 170