1BEGIN { 2 unshift @INC, 't/lib'; 3} 4 5use strict; 6use Test::More tests => 31; 7 8use Data::Dumper; 9use File::Temp; 10use Cwd; 11use Parse::CPAN::Meta; 12 13require ExtUtils::MM_Any; 14 15sub in_dir(&;$) { 16 my $code = shift; 17 my $dir = shift || File::Temp->newdir; 18 19 # chdir to the new directory 20 my $orig_dir = cwd(); 21 chdir $dir or die "Can't chdir to $dir: $!"; 22 23 # Run the code, but trap the error so we can chdir back 24 my $return; 25 my $ok = eval { $return = $code->(); 1; }; 26 my $err = $@; 27 28 # chdir back 29 chdir $orig_dir or die "Can't chdir to $orig_dir: $!"; 30 31 # rethrow if necessary 32 die $err unless $ok; 33 34 return $return; 35} 36 37sub mymeta_ok { 38 my($have, $want, $name) = @_; 39 40 local $Test::Builder::Level = $Test::Builder::Level + 1; 41 42 my $have_gen = delete $have->{generated_by}; 43 my $want_gen = delete $want->{generated_by}; 44 my $have_url = delete $have->{'meta-spec'}->{url}; 45 my $want_url = delete $want->{'meta-spec'}->{url}; 46 47 is_deeply $have, $want, $name; 48 like $have_gen, qr{CPAN::Meta}, "CPAN::Meta mentioned in the generated_by"; 49 like $have_url, qr{CPAN::Meta::Spec}, "CPAN::Meta::Spec mentioned in meta-spec URL"; 50 51 return; 52} 53 54my $new_mm = sub { 55 return bless { ARGS => {@_}, @_ }, 'ExtUtils::MM_Any'; 56}; 57 58{ 59 my $mm = $new_mm->( 60 DISTNAME => 'Foo-Bar', 61 VERSION => 1.23, 62 PM => { 63 "Foo::Bar" => 'lib/Foo/Bar.pm', 64 }, 65 ); 66 67 is_deeply {$mm->metafile_data}, { 68 name => 'Foo-Bar', 69 version => 1.23, 70 abstract => 'unknown', 71 author => [], 72 license => 'unknown', 73 dynamic_config => 1, 74 distribution_type => 'module', 75 76 configure_requires => { 77 'ExtUtils::MakeMaker' => 0, 78 }, 79 build_requires => { 80 'ExtUtils::MakeMaker' => 0, 81 }, 82 83 no_index => { 84 directory => [qw(t inc)], 85 }, 86 87 generated_by => "ExtUtils::MakeMaker version $ExtUtils::MakeMaker::VERSION", 88 'meta-spec' => { 89 url => 'http://module-build.sourceforge.net/META-spec-v1.4.html', 90 version => 1.4 91 }, 92 }; 93 94 95 is_deeply {$mm->metafile_data({}, { no_index => { directory => [qw(foo)] } })}, { 96 name => 'Foo-Bar', 97 version => 1.23, 98 abstract => 'unknown', 99 author => [], 100 license => 'unknown', 101 dynamic_config => 1, 102 distribution_type => 'module', 103 104 configure_requires => { 105 'ExtUtils::MakeMaker' => 0, 106 }, 107 build_requires => { 108 'ExtUtils::MakeMaker' => 0, 109 }, 110 111 no_index => { 112 directory => [qw(t inc foo)], 113 }, 114 115 generated_by => "ExtUtils::MakeMaker version $ExtUtils::MakeMaker::VERSION", 116 'meta-spec' => { 117 url => 'http://module-build.sourceforge.net/META-spec-v1.4.html', 118 version => 1.4 119 }, 120 }, 'rt.cpan.org 39348'; 121} 122 123 124{ 125 my $mm = $new_mm->( 126 DISTNAME => 'Foo-Bar', 127 VERSION => 1.23, 128 AUTHOR => ['Some Guy'], 129 PREREQ_PM => { 130 Foo => 2.34, 131 Bar => 4.56, 132 }, 133 ); 134 135 is_deeply {$mm->metafile_data( 136 { 137 configure_requires => { 138 Stuff => 2.34 139 }, 140 wobble => 42 141 }, 142 { 143 no_index => { 144 package => "Thing" 145 }, 146 wibble => 23 147 }, 148 )}, 149 { 150 name => 'Foo-Bar', 151 version => 1.23, 152 abstract => 'unknown', 153 author => ['Some Guy'], 154 license => 'unknown', 155 dynamic_config => 1, 156 distribution_type => 'script', 157 158 configure_requires => { 159 Stuff => 2.34, 160 }, 161 build_requires => { 162 'ExtUtils::MakeMaker' => 0, 163 }, 164 165 requires => { 166 Foo => 2.34, 167 Bar => 4.56, 168 }, 169 170 no_index => { 171 directory => [qw(t inc)], 172 package => 'Thing', 173 }, 174 175 generated_by => "ExtUtils::MakeMaker version $ExtUtils::MakeMaker::VERSION", 176 'meta-spec' => { 177 url => 'http://module-build.sourceforge.net/META-spec-v1.4.html', 178 version => 1.4 179 }, 180 181 wibble => 23, 182 wobble => 42, 183 }; 184} 185 186 187# Test MIN_PERL_VERSION meta-spec 1.4 188{ 189 my $mm = $new_mm->( 190 DISTNAME => 'Foo-Bar', 191 VERSION => 1.23, 192 PM => { 193 "Foo::Bar" => 'lib/Foo/Bar.pm', 194 }, 195 MIN_PERL_VERSION => 5.006, 196 ); 197 198 is_deeply {$mm->metafile_data}, { 199 name => 'Foo-Bar', 200 version => 1.23, 201 abstract => 'unknown', 202 author => [], 203 license => 'unknown', 204 dynamic_config => 1, 205 distribution_type => 'module', 206 207 configure_requires => { 208 'ExtUtils::MakeMaker' => 0, 209 }, 210 build_requires => { 211 'ExtUtils::MakeMaker' => 0, 212 }, 213 214 requires => { 215 perl => '5.006', 216 }, 217 218 no_index => { 219 directory => [qw(t inc)], 220 }, 221 222 generated_by => "ExtUtils::MakeMaker version $ExtUtils::MakeMaker::VERSION", 223 'meta-spec' => { 224 url => 'http://module-build.sourceforge.net/META-spec-v1.4.html', 225 version => 1.4 226 }, 227 }, 'MIN_PERL_VERSION meta-spec 1.4'; 228} 229 230# Test MIN_PERL_VERSION meta-spec 2.0 231{ 232 my $mm = $new_mm->( 233 DISTNAME => 'Foo-Bar', 234 VERSION => 1.23, 235 PM => { 236 "Foo::Bar" => 'lib/Foo/Bar.pm', 237 }, 238 MIN_PERL_VERSION => 5.006, 239 ); 240 241 is_deeply { 242 $mm->metafile_data( 243 {}, { 244 'meta-spec' => { 245 url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', 246 version => 2 247 } } ) 248 }, { 249 name => 'Foo-Bar', 250 version => 1.23, 251 abstract => 'unknown', 252 author => [], 253 license => 'unknown', 254 dynamic_config => 1, 255 distribution_type => 'module', 256 257 prereqs => { 258 configure => { 259 requires => { 260 'ExtUtils::MakeMaker' => 0, 261 }, 262 }, 263 build => { 264 requires => { 265 'ExtUtils::MakeMaker' => 0, 266 }, 267 }, 268 runtime => { 269 requires => { 270 'perl' => '5.006', 271 }, 272 }, 273 }, 274 275 no_index => { 276 directory => [qw(t inc)], 277 }, 278 279 generated_by => "ExtUtils::MakeMaker version $ExtUtils::MakeMaker::VERSION", 280 'meta-spec' => { 281 282 url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', 283 version => 2 284 }, 285 }, 'MIN_PERL_VERSION meta-spec 2.0'; 286} 287 288# Test MIN_PERL_VERSION meta-spec 1.4 289{ 290 my $mm = $new_mm->( 291 DISTNAME => 'Foo-Bar', 292 VERSION => 1.23, 293 PM => { 294 "Foo::Bar" => 'lib/Foo/Bar.pm', 295 }, 296 MIN_PERL_VERSION => 5.006, 297 PREREQ_PM => { 298 'Foo::Bar' => 1.23, 299 }, 300 ); 301 302 is_deeply {$mm->metafile_data}, { 303 name => 'Foo-Bar', 304 version => 1.23, 305 abstract => 'unknown', 306 author => [], 307 license => 'unknown', 308 dynamic_config => 1, 309 distribution_type => 'module', 310 311 configure_requires => { 312 'ExtUtils::MakeMaker' => 0, 313 }, 314 build_requires => { 315 'ExtUtils::MakeMaker' => 0, 316 }, 317 318 requires => { 319 perl => '5.006', 320 'Foo::Bar' => 1.23, 321 }, 322 323 no_index => { 324 directory => [qw(t inc)], 325 }, 326 327 generated_by => "ExtUtils::MakeMaker version $ExtUtils::MakeMaker::VERSION", 328 'meta-spec' => { 329 url => 'http://module-build.sourceforge.net/META-spec-v1.4.html', 330 version => 1.4 331 }, 332 }, 'MIN_PERL_VERSION and PREREQ_PM meta-spec 1.4'; 333} 334 335# Test CONFIGURE_REQUIRES meta-spec 1.4 336{ 337 my $mm = $new_mm->( 338 DISTNAME => 'Foo-Bar', 339 VERSION => 1.23, 340 CONFIGURE_REQUIRES => { 341 "Fake::Module1" => 1.01, 342 }, 343 PM => { 344 "Foo::Bar" => 'lib/Foo/Bar.pm', 345 }, 346 ); 347 348 is_deeply {$mm->metafile_data}, { 349 name => 'Foo-Bar', 350 version => 1.23, 351 abstract => 'unknown', 352 author => [], 353 license => 'unknown', 354 dynamic_config => 1, 355 distribution_type => 'module', 356 357 configure_requires => { 358 'Fake::Module1' => 1.01, 359 }, 360 build_requires => { 361 'ExtUtils::MakeMaker' => 0, 362 }, 363 364 no_index => { 365 directory => [qw(t inc)], 366 }, 367 368 generated_by => "ExtUtils::MakeMaker version $ExtUtils::MakeMaker::VERSION", 369 'meta-spec' => { 370 url => 'http://module-build.sourceforge.net/META-spec-v1.4.html', 371 version => 1.4 372 }, 373 },'CONFIGURE_REQUIRES meta-spec 1.4'; 374} 375 376# Test CONFIGURE_REQUIRES meta-spec 2.0 377{ 378 my $mm = $new_mm->( 379 DISTNAME => 'Foo-Bar', 380 VERSION => 1.23, 381 CONFIGURE_REQUIRES => { 382 "Fake::Module1" => 1.01, 383 }, 384 PM => { 385 "Foo::Bar" => 'lib/Foo/Bar.pm', 386 }, 387 ); 388 389 is_deeply { 390 $mm->metafile_data( 391 {}, { 392 'meta-spec' => { 393 url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', 394 version => 2 395 } } ) 396 }, { 397 name => 'Foo-Bar', 398 version => 1.23, 399 abstract => 'unknown', 400 author => [], 401 license => 'unknown', 402 dynamic_config => 1, 403 distribution_type => 'module', 404 405 prereqs => { 406 configure => { 407 requires => { 408 'Fake::Module1' => 1.01, 409 }, 410 }, 411 build => { 412 requires => { 413 'ExtUtils::MakeMaker' => 0, 414 }, 415 }, 416 }, 417 418 no_index => { 419 directory => [qw(t inc)], 420 }, 421 422 generated_by => "ExtUtils::MakeMaker version $ExtUtils::MakeMaker::VERSION", 423 'meta-spec' => { 424 url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', 425 version => 2 426 }, 427 },'CONFIGURE_REQUIRES meta-spec 2.0'; 428} 429 430 431# Test BUILD_REQUIRES meta-spec 1.4 432{ 433 my $mm = $new_mm->( 434 DISTNAME => 'Foo-Bar', 435 VERSION => 1.23, 436 BUILD_REQUIRES => { 437 "Fake::Module1" => 1.01, 438 }, 439 PM => { 440 "Foo::Bar" => 'lib/Foo/Bar.pm', 441 }, 442 ); 443 444 is_deeply {$mm->metafile_data}, { 445 name => 'Foo-Bar', 446 version => 1.23, 447 abstract => 'unknown', 448 author => [], 449 license => 'unknown', 450 dynamic_config => 1, 451 distribution_type => 'module', 452 453 configure_requires => { 454 'ExtUtils::MakeMaker' => 0, 455 }, 456 build_requires => { 457 'Fake::Module1' => 1.01, 458 }, 459 460 no_index => { 461 directory => [qw(t inc)], 462 }, 463 464 generated_by => "ExtUtils::MakeMaker version $ExtUtils::MakeMaker::VERSION", 465 'meta-spec' => { 466 url => 'http://module-build.sourceforge.net/META-spec-v1.4.html', 467 version => 1.4 468 }, 469 },'BUILD_REQUIRES meta-spec 1.4'; 470} 471 472# Test BUILD_REQUIRES meta-spec 2.0 473{ 474 my $mm = $new_mm->( 475 DISTNAME => 'Foo-Bar', 476 VERSION => 1.23, 477 BUILD_REQUIRES => { 478 "Fake::Module1" => 1.01, 479 }, 480 PM => { 481 "Foo::Bar" => 'lib/Foo/Bar.pm', 482 }, 483 META_MERGE => { "meta-spec" => { version => 2 }}, 484 ); 485 486 is_deeply { 487 $mm->metafile_data( 488 {}, { 489 'meta-spec' => { 490 url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', 491 version => 2 492 } } ) 493 }, { 494 name => 'Foo-Bar', 495 version => 1.23, 496 abstract => 'unknown', 497 author => [], 498 license => 'unknown', 499 dynamic_config => 1, 500 distribution_type => 'module', 501 502 prereqs => { 503 configure => { 504 requires => { 505 'ExtUtils::MakeMaker' => 0, 506 }, 507 }, 508 build => { 509 requires => { 510 'Fake::Module1' => 1.01, 511 }, 512 }, 513 }, 514 515 no_index => { 516 directory => [qw(t inc)], 517 }, 518 519 generated_by => "ExtUtils::MakeMaker version $ExtUtils::MakeMaker::VERSION", 520 'meta-spec' => { 521 url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', 522 version => 2 523 }, 524 },'BUILD_REQUIRES meta-spec 2.0'; 525} 526 527# Test TEST_REQUIRES meta-spec 1.4 528{ 529 my $mm = $new_mm->( 530 DISTNAME => 'Foo-Bar', 531 VERSION => 1.23, 532 TEST_REQUIRES => { 533 "Fake::Module1" => 1.01, 534 }, 535 PM => { 536 "Foo::Bar" => 'lib/Foo/Bar.pm', 537 }, 538 ); 539 540 is_deeply {$mm->metafile_data}, { 541 name => 'Foo-Bar', 542 version => 1.23, 543 abstract => 'unknown', 544 author => [], 545 license => 'unknown', 546 dynamic_config => 1, 547 distribution_type => 'module', 548 549 configure_requires => { 550 'ExtUtils::MakeMaker' => 0, 551 }, 552 build_requires => { 553 'ExtUtils::MakeMaker' => 0, 554 'Fake::Module1' => 1.01, 555 }, 556 557 no_index => { 558 directory => [qw(t inc)], 559 }, 560 561 generated_by => "ExtUtils::MakeMaker version $ExtUtils::MakeMaker::VERSION", 562 'meta-spec' => { 563 url => 'http://module-build.sourceforge.net/META-spec-v1.4.html', 564 version => 1.4 565 }, 566 },'TEST_REQUIRES meta-spec 1.4'; 567} 568 569# Test TEST_REQUIRES meta-spec 2.0 570{ 571 my $mm = $new_mm->( 572 DISTNAME => 'Foo-Bar', 573 VERSION => 1.23, 574 TEST_REQUIRES => { 575 "Fake::Module1" => 1.01, 576 }, 577 PM => { 578 "Foo::Bar" => 'lib/Foo/Bar.pm', 579 }, 580 META_MERGE => { "meta-spec" => { version => 2 }}, 581 ); 582 583 is_deeply { 584 $mm->metafile_data( 585 {}, { 586 'meta-spec' => { 587 url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', 588 version => 2 589 } } ) 590 }, { 591 name => 'Foo-Bar', 592 version => 1.23, 593 abstract => 'unknown', 594 author => [], 595 license => 'unknown', 596 dynamic_config => 1, 597 distribution_type => 'module', 598 599 prereqs => { 600 configure => { 601 requires => { 602 'ExtUtils::MakeMaker' => 0, 603 }, 604 }, 605 build => { 606 requires => { 607 'ExtUtils::MakeMaker' => 0, 608 }, 609 }, 610 test => { 611 requires => { 612 "Fake::Module1" => 1.01, 613 }, 614 }, 615 }, 616 617 no_index => { 618 directory => [qw(t inc)], 619 }, 620 621 generated_by => "ExtUtils::MakeMaker version $ExtUtils::MakeMaker::VERSION", 622 'meta-spec' => { 623 url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', 624 version => 2 625 }, 626 },'TEST_REQUIRES meta-spec 2.0'; 627} 628 629 630# Test _REQUIRES key priority over META_ADD 631 632{ 633 my $mm = $new_mm->( 634 DISTNAME => 'Foo-Bar', 635 VERSION => 1.23, 636 BUILD_REQUIRES => { 637 "Fake::Module1" => 1.01, 638 }, 639 META_ADD => (my $meta_add = { build_requires => {}, configure_requires => {} }), 640 PM => { 641 "Foo::Bar" => 'lib/Foo/Bar.pm', 642 }, 643 ); 644 645 is_deeply {$mm->metafile_data($meta_add)}, { 646 name => 'Foo-Bar', 647 version => 1.23, 648 abstract => 'unknown', 649 author => [], 650 license => 'unknown', 651 dynamic_config => 1, 652 distribution_type => 'module', 653 654 configure_requires => { }, 655 build_requires => { }, 656 657 no_index => { 658 directory => [qw(t inc)], 659 }, 660 661 generated_by => "ExtUtils::MakeMaker version $ExtUtils::MakeMaker::VERSION", 662 'meta-spec' => { 663 url => 'http://module-build.sourceforge.net/META-spec-v1.4.html', 664 version => 1.4 665 }, 666 },'META.yml data (META_ADD wins)'; 667 668 669 # Yes, this is all hard coded. 670 require CPAN::Meta; 671 my $want_mymeta = { 672 name => 'ExtUtils-MakeMaker', 673 version => '6.57_07', 674 abstract => 'Create a module Makefile', 675 author => ['Michael G Schwern <schwern@pobox.com>'], 676 license => ['perl_5'], 677 dynamic_config => 0, 678 679 prereqs => { 680 runtime => { 681 requires => { 682 "DirHandle" => 0, 683 "File::Basename" => 0, 684 "File::Spec" => "0.8", 685 "Pod::Man" => 0, 686 "perl" => "5.006", 687 }, 688 }, 689 configure => { 690 requires => { 691 'ExtUtils::MakeMaker' => 0, 692 }, 693 }, 694 build => { 695 requires => { 696 'Fake::Module1' => 1.01, 697 }, 698 }, 699 }, 700 701 release_status => 'testing', 702 resources => { 703 license => [ 'http://dev.perl.org/licenses/' ], 704 homepage => 'http://makemaker.org', 705 bugtracker => { web => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker' }, 706 repository => { url => 'http://github.com/Perl-Toolchain-Gang/ExtUtils-MakeMaker' }, 707 x_MailingList => 'makemaker@perl.org', 708 }, 709 710 no_index => { 711 directory => [qw(t inc)], 712 package => ["DynaLoader", "in"], 713 }, 714 715 generated_by => "ExtUtils::MakeMaker version 6.5707, CPAN::Meta::Converter version 2.110580", 716 'meta-spec' => { 717 url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', 718 version => 2, 719 }, 720 }; 721 722 mymeta_ok $mm->mymeta("t/META_for_testing.json"), 723 $want_mymeta, 724 'MYMETA JSON data (BUILD_REQUIRES wins)'; 725 726 mymeta_ok $mm->mymeta("t/META_for_testing.yml"), 727 $want_mymeta, 728 'MYMETA YAML data (BUILD_REQUIRES wins)'; 729} 730 731{ 732 my $mm = $new_mm->( 733 DISTNAME => 'Foo-Bar', 734 VERSION => 1.23, 735 CONFIGURE_REQUIRES => { "Fake::Module0" => 0.99 }, 736 BUILD_REQUIRES => { "Fake::Module1" => 1.01 }, 737 TEST_REQUIRES => { "Fake::Module2" => 1.23 }, 738 ); 739 740 my $meta = $mm->mymeta('t/META_for_testing.json'); 741 is($meta->{configure_requires}, undef, "no configure_requires in v2 META"); 742 is($meta->{build_requires}, undef, "no build_requires in v2 META"); 743 is_deeply( 744 $meta->{prereqs}{configure}{requires}, 745 { "Fake::Module0" => 0.99 }, 746 "configure requires are one thing in META v2...", 747 ); 748 749 is_deeply( 750 $meta->{prereqs}{build}{requires}, 751 { "Fake::Module1" => 1.01 }, 752 "build requires are one thing in META v2...", 753 ); 754 755 is_deeply( 756 $meta->{prereqs}{test}{requires}, 757 { "Fake::Module2" => 1.23 }, 758 "...and test requires are another", 759 ); 760} 761 762note "CPAN::Meta bug using the module version instead of the meta spec version"; { 763 my $mm = $new_mm->( 764 NAME => 'GD::Barcode::Code93', 765 AUTHOR => 'Chris DiMartino', 766 ABSTRACT => 'Code 93 implementation of GD::Barcode family', 767 PREREQ_PM => { 768 'GD::Barcode' => 0, 769 'GD' => 0 770 }, 771 VERSION => '1.4', 772 ); 773 774 my $meta = $mm->mymeta("t/META_for_testing_tricky_version.yml"); 775 is $meta->{'meta-spec'}{version}, 2, "internally, our MYMETA struct is v2"; 776 777 in_dir { 778 $mm->write_mymeta($meta); 779 ok -e "MYMETA.yml"; 780 ok -e "MYMETA.json"; 781 782 my $meta_yml = Parse::CPAN::Meta->load_file("MYMETA.yml"); 783 is $meta_yml->{'meta-spec'}{version}, 1.4, "MYMETA.yml correctly downgraded to 1.4"; 784 785 my $meta_json = Parse::CPAN::Meta->load_file("MYMETA.json"); 786 cmp_ok $meta_json->{'meta-spec'}{version}, ">=", 2, "MYMETA.json at 2 or better"; 787 }; 788} 789 790 791note "A bad license string"; { 792 my $mm = $new_mm->( 793 DISTNAME => 'Foo::Bar', 794 VERSION => '1.4', 795 LICENSE => 'death and retribution', 796 ); 797 798 in_dir { 799 my $meta = $mm->mymeta; 800 $mm->write_mymeta($meta); 801 802 my $meta_yml = Parse::CPAN::Meta->load_file("MYMETA.yml"); 803 is $meta_yml->{license}, "unknown", "in yaml"; 804 805 my $meta_json = Parse::CPAN::Meta->load_file("MYMETA.json"); 806 is_deeply $meta_json->{license}, ["unknown"], "in json"; 807 }; 808} 809