xref: /openbsd-src/gnu/usr.bin/perl/cpan/ExtUtils-MakeMaker/t/metafile_data.t (revision 46035553bfdd96e63c94e32da0210227ec2e3cf1)
1BEGIN {
2    unshift @INC, 't/lib';
3}
4
5use strict;
6use Test::More;
7BEGIN {
8  eval { require CPAN::Meta; CPAN::Meta->VERSION(2.143240) }
9    or plan skip_all => 'CPAN::Meta 2.143240 required for this test';
10  eval { require CPAN::Meta::Converter; }
11    or plan skip_all => 'CPAN::Meta::Converter required for this test';
12  eval { require Parse::CPAN::Meta; }
13    or plan skip_all => 'Parse::CPAN::Meta required for this test';
14}
15use Data::Dumper;
16use File::Temp;
17use Cwd;
18use MakeMaker::Test::Utils;
19
20plan tests => 35;
21require ExtUtils::MM_Any;
22
23sub mymeta_ok {
24    my($have, $want, $name) = @_;
25    local $Test::Builder::Level = $Test::Builder::Level + 1;
26    my $have_gen = delete $have->{generated_by};
27    my $want_gen = delete $want->{generated_by};
28    my $have_url = delete $have->{'meta-spec'}->{url};
29    my $want_url = delete $want->{'meta-spec'}->{url};
30    is_deeply $have, $want, $name;
31    like $have_gen, qr{CPAN::Meta}, "CPAN::Meta mentioned in the generated_by";
32    like $have_url, qr{CPAN::Meta::Spec}, "CPAN::Meta::Spec mentioned in meta-spec URL";
33    return;
34}
35
36my $new_mm = sub {
37    return bless { ARGS => {@_}, @_ }, 'ExtUtils::MM_Any';
38};
39my @METASPEC14 = (
40    'meta-spec'  => {
41        url => 'http://module-build.sourceforge.net/META-spec-v1.4.html',
42        version => 1.4
43    },
44);
45my @METASPEC20 = (
46    'meta-spec'  => {
47        url => 'https://metacpan.org/pod/CPAN::Meta::Spec',
48        version => 2
49    },
50);
51my @REQ20 = (
52    configure => { requires => { 'ExtUtils::MakeMaker' => 0, }, },
53    build => { requires => { 'ExtUtils::MakeMaker' => 0, }, },
54);
55my @GENERIC_IN = (
56    DISTNAME => 'Foo-Bar',
57    VERSION  => 1.23,
58    PM       => { "Foo::Bar" => 'lib/Foo/Bar.pm', },
59);
60my @GENERIC_OUT = (
61    # mandatory
62    abstract          => 'unknown',
63    author            => [qw(unknown)],
64    dynamic_config    => 1,
65    generated_by      => "ExtUtils::MakeMaker version $ExtUtils::MakeMaker::VERSION",
66    license           => ['unknown'],
67    @METASPEC20,
68    name              => 'Foo-Bar',
69    release_status    => 'stable',
70    version           => 1.23,
71    # optional
72    no_index          => { directory => [qw(t inc)], },
73);
74
75{
76    my $mm = $new_mm->(@GENERIC_IN);
77    is_deeply $mm->metafile_data, {
78        @GENERIC_OUT,
79        prereqs => { @REQ20, },
80    };
81    is_deeply $mm->metafile_data({}, { no_index => { directory => [qw(foo)] } }), {
82        @GENERIC_OUT,
83        prereqs => { @REQ20, },
84        no_index        => { directory => [qw(t inc foo)], },
85    }, 'rt.cpan.org 39348';
86}
87
88{
89    my $mm = $new_mm->(
90        DISTNAME        => 'Foo-Bar',
91        VERSION         => 1.23,
92        AUTHOR          => ['Some Guy'],
93        PREREQ_PM       => { Foo => 2.34, Bar => 4.56, },
94    );
95    is_deeply $mm->metafile_data(
96        {
97            configure_requires => { Stuff   => 2.34 },
98            wobble      => 42
99        },
100        {
101            no_index    => { package => "Thing" },
102            wibble      => 23
103        },
104    ),
105    {
106        @GENERIC_OUT, # some overridden, which is fine
107        author          => ['Some Guy'],
108        prereqs => {
109            @REQ20,
110            configure => { requires => { Stuff => 2.34, }, },
111            runtime => { requires => { Foo => 2.34, Bar => 4.56, }, },
112        },
113        no_index        => {
114            directory           => [qw(t inc)],
115            package             => ['Thing'],
116        },
117        x_wibble  => 23,
118        x_wobble  => 42,
119    }, '_add vs _merge';
120}
121
122# Test MIN_PERL_VERSION meta-spec 1.4
123{
124    my $mm = $new_mm->(
125        @GENERIC_IN,
126        MIN_PERL_VERSION => 5.006,
127    );
128    is_deeply $mm->metafile_data( {}, { @METASPEC14 }, ), {
129        @GENERIC_OUT,
130        prereqs => {
131            @REQ20,
132            runtime => { requires => { perl => 5.006, }, },
133        },
134    }, 'MIN_PERL_VERSION meta-spec 1.4';
135}
136
137# Test MIN_PERL_VERSION meta-spec 2.0
138{
139    my $mm = $new_mm->(
140        @GENERIC_IN,
141        MIN_PERL_VERSION => 5.006,
142    );
143    is_deeply $mm->metafile_data, {
144        prereqs => {
145            @REQ20,
146            runtime => { requires => { 'perl' => '5.006', }, },
147        },
148        @GENERIC_OUT,
149    }, 'MIN_PERL_VERSION meta-spec 2.0';
150}
151
152# Test MIN_PERL_VERSION meta-spec 1.4
153{
154    my $mm = $new_mm->(
155        @GENERIC_IN,
156        MIN_PERL_VERSION => 5.006,
157        PREREQ_PM => { 'Foo::Bar' => 1.23, },
158    );
159    is_deeply $mm->metafile_data, {
160        @GENERIC_OUT,
161        prereqs => {
162            @REQ20,
163            runtime         => {
164                requires    => {
165                    'Foo::Bar'  => 1.23,
166                    'perl'  => '5.006',
167                },
168            },
169        },
170    }, 'MIN_PERL_VERSION and PREREQ_PM meta-spec 1.4';
171}
172
173# Test CONFIGURE_REQUIRES meta-spec 1.4
174{
175    my $mm = $new_mm->(
176        @GENERIC_IN,
177        CONFIGURE_REQUIRES => { "Fake::Module1" => 1.01, },
178    );
179    is_deeply $mm->metafile_data( {}, { @METASPEC14 }, ), {
180        prereqs => {
181            @REQ20,
182            configure => { requires => { 'Fake::Module1' => 1.01, }, },
183        },
184        @GENERIC_OUT,
185    },'CONFIGURE_REQUIRES meta-spec 1.4';
186}
187
188# Test CONFIGURE_REQUIRES meta-spec 2.0
189{
190    my $mm = $new_mm->(
191        @GENERIC_IN,
192        CONFIGURE_REQUIRES => { "Fake::Module1" => 1.01, },
193    );
194    is_deeply $mm->metafile_data, {
195        prereqs => {
196            @REQ20,
197            configure => { requires => { 'Fake::Module1' => 1.01, }, },
198        },
199        @GENERIC_OUT,
200    },'CONFIGURE_REQUIRES meta-spec 2.0';
201}
202
203# Test BUILD_REQUIRES meta-spec 1.4
204{
205    my $mm = $new_mm->(
206        @GENERIC_IN,
207        BUILD_REQUIRES => { "Fake::Module1" => 1.01, },
208        META_MERGE => { "meta-spec" => { version => 1.4 }},
209    );
210    is_deeply $mm->metafile_data( {}, { @METASPEC14 }, ), {
211        prereqs => {
212            @REQ20,
213            build => { requires => { 'Fake::Module1' => 1.01, }, },
214        },
215        @GENERIC_OUT,
216    },'BUILD_REQUIRES meta-spec 1.4';
217}
218
219# Test BUILD_REQUIRES meta-spec 2.0
220{
221    my $mm = $new_mm->(
222        @GENERIC_IN,
223        BUILD_REQUIRES => { "Fake::Module1" => 1.01, },
224    );
225    is_deeply $mm->metafile_data, {
226        prereqs => {
227            @REQ20,
228            build => { requires => { 'Fake::Module1' => 1.01, }, },
229        },
230        @GENERIC_OUT,
231    },'BUILD_REQUIRES meta-spec 2.0';
232}
233
234# Test TEST_REQUIRES meta-spec 1.4
235{
236    my $mm = $new_mm->(
237        @GENERIC_IN,
238        TEST_REQUIRES => { "Fake::Module1" => 1.01, },
239        META_MERGE => { "meta-spec" => { version => 1.4 }},
240    );
241    is_deeply $mm->metafile_data( {}, { @METASPEC14 }, ), {
242        prereqs => {
243            @REQ20,
244            test => { requires => { "Fake::Module1" => 1.01, }, },
245        },
246        @GENERIC_OUT,
247    },'TEST_REQUIRES meta-spec 1.4';
248}
249
250# Test TEST_REQUIRES meta-spec 2.0
251{
252    my $mm = $new_mm->(
253        @GENERIC_IN,
254        TEST_REQUIRES => { "Fake::Module1" => 1.01, },
255    );
256    is_deeply $mm->metafile_data, {
257        prereqs => {
258            @REQ20,
259            test => { requires => { "Fake::Module1" => 1.01, }, },
260        },
261        @GENERIC_OUT,
262    },'TEST_REQUIRES meta-spec 2.0';
263}
264
265{
266    my $mm = $new_mm->(
267        @GENERIC_IN,
268    );
269    is_deeply $mm->metafile_data(
270        {
271            resources => {
272                homepage => "https://metacpan.org/release/ExtUtils-MakeMaker",
273                repository => "http://github.com/Perl-Toolchain-Gang/ExtUtils-MakeMaker",
274            },
275        },
276        { @METASPEC14 },
277    ), {
278        prereqs => { @REQ20 },
279        resources => {
280            homepage => "https://metacpan.org/release/ExtUtils-MakeMaker",
281            repository => {
282                url => "http://github.com/Perl-Toolchain-Gang/ExtUtils-MakeMaker",
283            },
284        },
285        @GENERIC_OUT,
286    }, 'META_ADD takes meta version 1.4 from META_MERGE';
287}
288
289{
290    my $mm = $new_mm->(
291        @GENERIC_IN,
292    );
293    is_deeply $mm->metafile_data(
294        { @METASPEC14 },
295        {
296            resources => {
297                homepage => "https://metacpan.org/release/ExtUtils-MakeMaker",
298                repository => "http://github.com/Perl-Toolchain-Gang/ExtUtils-MakeMaker",
299            },
300        },
301    ), {
302        prereqs => { @REQ20 },
303        resources => {
304            homepage => "https://metacpan.org/release/ExtUtils-MakeMaker",
305            repository => {
306                url => "http://github.com/Perl-Toolchain-Gang/ExtUtils-MakeMaker",
307            },
308        },
309        @GENERIC_OUT,
310    }, 'META_MERGE takes meta version 1.4 from META_ADD';
311}
312
313{
314    my $mm = $new_mm->(
315        @GENERIC_IN,
316    );
317    is_deeply $mm->metafile_data(
318        {
319            'configure_requires' => {
320                'Fake::Module1' => 1,
321            },
322            'prereqs' => {
323                @REQ20,
324                'test' => {
325                    'requires' => {
326                        'Fake::Module2' => 2,
327                    },
328                },
329            },
330        },
331        { @METASPEC20 },
332    ), {
333        prereqs => {
334            @REQ20,
335            test => { requires => { "Fake::Module2" => 2, }, },
336        },
337        @GENERIC_OUT,
338    }, 'META_ADD takes meta version 2 from META_MERGE';
339}
340
341{
342    my $mm = $new_mm->(
343        @GENERIC_IN,
344    );
345    is_deeply $mm->metafile_data(
346        { @METASPEC20 },
347        {
348            'configure_requires' => {
349                'Fake::Module1' => 1,
350            },
351            'prereqs' => {
352                @REQ20,
353                'test' => {
354                    'requires' => {
355                        'Fake::Module2' => 2,
356                    },
357                },
358            },
359        },
360    ), {
361        prereqs => {
362            @REQ20,
363            test => { requires => { "Fake::Module2" => 2, }, },
364        },
365        @GENERIC_OUT,
366    }, 'META_MERGE takes meta version 2 from META_ADD';
367}
368
369# Test _REQUIRES key priority over META_ADD
370{
371    my $mm = $new_mm->(
372        @GENERIC_IN,
373        BUILD_REQUIRES => { "Fake::Module1" => 1.01, },
374        META_ADD => (my $meta_add = { build_requires => {}, configure_requires => {} }),
375    );
376    is_deeply $mm->metafile_data($meta_add), {
377        prereqs => {
378            configure => { requires => { }, },
379            build => { requires => { }, },
380        },
381        @GENERIC_OUT,
382    },'META.yml data (META_ADD wins)';
383    # Yes, this is all hard coded.
384
385    my $want_mymeta = {
386        name            => 'ExtUtils-MakeMaker',
387        version         => '6.57_07',
388        abstract        => 'Create a module Makefile',
389        author          => ['Michael G Schwern <schwern@pobox.com>'],
390        license         => ['perl_5'],
391        dynamic_config  => 0,
392        prereqs => {
393            runtime => {
394                requires => {
395                    "DirHandle"         => 0,
396                    "File::Basename"    => 0,
397                    "File::Spec"        => "0.8",
398                    "Pod::Man"          => 0,
399                    "perl"              => "5.006",
400                },
401            },
402            @REQ20,
403            build => { requires => { 'Fake::Module1' => 1.01, }, },
404        },
405        release_status => 'testing',
406        resources => {
407            license     =>  [ 'http://dev.perl.org/licenses/' ],
408            homepage    =>  'http://makemaker.org',
409            bugtracker  =>  { web => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker' },
410            repository  =>  { url => 'http://github.com/Perl-Toolchain-Gang/ExtUtils-MakeMaker' },
411            x_MailingList => 'makemaker@perl.org',
412        },
413        no_index        => {
414            directory           => [qw(t inc)],
415            package             => ["DynaLoader", "in"],
416        },
417        generated_by => "ExtUtils::MakeMaker version 6.5707, CPAN::Meta::Converter version 2.110580",
418        @METASPEC20,
419    };
420    mymeta_ok $mm->mymeta("t/META_for_testing.json"),
421              $want_mymeta,
422              'MYMETA JSON data (BUILD_REQUIRES wins)';
423    mymeta_ok $mm->mymeta("t/META_for_testing.yml"),
424              $want_mymeta,
425              'MYMETA YAML data (BUILD_REQUIRES wins)';
426}
427
428{
429    my $mm = $new_mm->(
430        @GENERIC_IN,
431        CONFIGURE_REQUIRES  => { "Fake::Module0" => 0.99 },
432        BUILD_REQUIRES      => { "Fake::Module1" => 1.01 },
433        TEST_REQUIRES       => { "Fake::Module2" => 1.23 },
434    );
435    my $meta = $mm->mymeta('t/META_for_testing.json');
436    is($meta->{configure_requires}, undef, "no configure_requires in v2 META");
437    is($meta->{build_requires}, undef, "no build_requires in v2 META");
438    is_deeply(
439        $meta->{prereqs}{configure}{requires},
440        { "Fake::Module0" => 0.99 },
441        "configure requires are one thing in META v2...",
442    );
443    is_deeply(
444        $meta->{prereqs}{build}{requires},
445        { "Fake::Module1" => 1.01 },
446        "build requires are one thing in META v2...",
447    );
448    is_deeply(
449        $meta->{prereqs}{test}{requires},
450        { "Fake::Module2" => 1.23 },
451        "...and test requires are another",
452    );
453}
454
455note "CPAN::Meta bug using the module version instead of the meta spec version";
456{
457    my $mm = $new_mm->(
458        NAME      => 'GD::Barcode::Code93',
459        AUTHOR    => 'Chris DiMartino',
460        ABSTRACT  => 'Code 93 implementation of GD::Barcode family',
461        PREREQ_PM => {
462            'GD::Barcode' => 0,
463            'GD'          => 0
464        },
465        VERSION   => '1.4',
466    );
467    my $meta = $mm->mymeta("t/META_for_testing_tricky_version.yml");
468    is $meta->{'meta-spec'}{version}, 2, "internally, our MYMETA struct is v2";
469    in_dir {
470        $mm->write_mymeta($meta);
471        ok -e "MYMETA.yml";
472        ok -e "MYMETA.json";
473        my $meta_yml = Parse::CPAN::Meta->load_file("MYMETA.yml");
474        is $meta_yml->{'meta-spec'}{version}, 1.4, "MYMETA.yml correctly downgraded to 1.4";
475        my $meta_json = Parse::CPAN::Meta->load_file("MYMETA.json");
476        cmp_ok $meta_json->{'meta-spec'}{version}, ">=", 2, "MYMETA.json at 2 or better";
477    };
478}
479
480note "A bad license string";
481{
482    my $mm = $new_mm->(
483        @GENERIC_IN,
484        LICENSE   => 'death and retribution',
485    );
486    in_dir {
487        my $meta = $mm->mymeta;
488        {
489            local $SIG{__WARN__} = sub {}; # suppress "Invalid" warning
490            $mm->write_mymeta($meta);
491        }
492        my $meta_yml = Parse::CPAN::Meta->load_file("MYMETA.yml");
493        is $meta_yml->{license}, "unknown", "in yaml";
494        my $meta_json = Parse::CPAN::Meta->load_file("MYMETA.json");
495        is_deeply $meta_json->{license}, ["unknown"], "in json";
496    };
497}
498