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