1use strict; 2use warnings; 3use Test::More 0.88; 4 5use CPAN::Meta; 6use Storable qw(dclone); 7use Scalar::Util qw(blessed); 8 9delete $ENV{PERL_YAML_BACKEND}; 10delete $ENV{PERL_JSON_BACKEND}; 11delete $ENV{CPAN_META_JSON_BACKEND}; 12delete $ENV{CPAN_META_JSON_DECODER}; 13 14my $distmeta = { 15 name => 'Module-Build', 16 abstract => 'Build and install Perl modules', 17 description => "Module::Build is a system for building, testing, " 18 . "and installing Perl modules. It is meant to be an " 19 . "alternative to ExtUtils::MakeMaker... blah blah blah", 20 version => '0.36', 21 author => [ 22 'Ken Williams <kwilliams@cpan.org>', 23 'Module-Build List <module-build@perl.org>', # additional contact 24 ], 25 release_status => 'stable', 26 license => [ 'perl_5' ], 27 prereqs => { 28 runtime => { 29 requires => { 30 'perl' => '5.006', 31 'Config' => '0', 32 'Cwd' => '0', 33 'Data::Dumper' => '0', 34 'ExtUtils::Install' => '0', 35 'File::Basename' => '0', 36 'File::Compare' => '0', 37 'File::Copy' => '0', 38 'File::Find' => '0', 39 'File::Path' => '0', 40 'File::Spec' => '0', 41 'IO::File' => '0', 42 }, 43 recommends => { 44 'Archive::Tar' => '1.00', 45 'ExtUtils::Install' => '0.3', 46 'ExtUtils::ParseXS' => '2.02', 47 'Pod::Text' => '0', 48 'YAML' => '0.35', 49 }, 50 }, 51 build => { 52 requires => { 53 'Test::More' => '0', 54 }, 55 } 56 }, 57 resources => { 58 license => ['http://dev.perl.org/licenses/'], 59 }, 60 optional_features => { 61 domination => { 62 description => 'Take over the world', 63 prereqs => { 64 develop => { requires => { 'Genius::Evil' => '1.234' } }, 65 runtime => { requires => { 'Machine::Weather' => '2.0' } }, 66 }, 67 }, 68 }, 69 dynamic_config => 1, 70 keywords => [ qw/ toolchain cpan dual-life / ], 71 'meta-spec' => { 72 version => '2', 73 url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', 74 }, 75 generated_by => 'Module::Build version 0.36', 76 x_authority => 'cpan:FLORA', 77 X_deep => { deep => 'structure' }, 78}; 79 80my $meta = CPAN::Meta->new(dclone $distmeta); 81 82is( 83 blessed($meta->as_struct), 84 undef, 85 "the result of ->as_struct is unblessed", 86); 87 88is_deeply( $meta->as_struct, $distmeta, "->as_struct (deep comparison)" ); 89isnt( $meta->as_struct, $distmeta, "->as_struct (is a deep clone)" ); 90 91my $old_copy = $meta->as_struct( {version => "1.4"} ); 92is( $old_copy->{'meta-spec'}{version}, "1.4", "->as_struct (downconversion)" ); 93 94isnt( $meta->resources, $meta->{resources}, "->resource (map values are deep cloned)"); 95 96is($meta->name, 'Module-Build', '->name'); 97is($meta->abstract, 'Build and install Perl modules', '->abstract'); 98 99like($meta->description, qr/Module::Build.+blah blah blah/, '->description'); 100 101is($meta->version, '0.36', '->version'); 102 103ok($meta->dynamic_config, "->dynamic_config"); 104 105is_deeply( 106 [ $meta->author ], 107 [ 108 'Ken Williams <kwilliams@cpan.org>', 109 'Module-Build List <module-build@perl.org>', 110 ], 111 '->author', 112); 113 114is_deeply( 115 [ $meta->authors ], 116 [ 117 'Ken Williams <kwilliams@cpan.org>', 118 'Module-Build List <module-build@perl.org>', 119 ], 120 '->authors', 121); 122 123is_deeply( 124 [ $meta->license ], 125 [ qw(perl_5) ], 126 '->license', 127); 128 129is_deeply( 130 [ $meta->licenses ], 131 [ qw(perl_5) ], 132 '->licenses', 133); 134 135is_deeply( 136 [ $meta->keywords ], 137 [ qw/ toolchain cpan dual-life / ], 138 '->keywords', 139); 140 141is_deeply( 142 $meta->resources, 143 { license => [ 'http://dev.perl.org/licenses/' ] }, 144 '->resources', 145); 146 147is_deeply( 148 $meta->meta_spec, 149 { 150 version => '2', 151 url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', 152 }, 153 '->meta_spec', 154); 155 156is($meta->meta_spec_version, '2', '->meta_spec_version'); 157 158like($meta->generated_by, qr/Module::Build version 0.36/, '->generated_by'); 159 160my $basic = $meta->effective_prereqs; 161 162is_deeply( 163 $basic->as_string_hash, 164 $distmeta->{prereqs}, 165 "->effective_prereqs()" 166); 167 168is_deeply( [ sort $meta->custom_keys ] , [ 'X_deep', 'x_authority' ], 169 "->custom_keys" 170); 171 172is( $meta->custom('x_authority'), 'cpan:FLORA', "->custom(X)" ); 173 174is_deeply( $meta->custom('X_deep'), $distmeta->{'X_deep'}, 175 "->custom(X) [is_deeply]" 176); 177 178isnt( $meta->custom('X_deep'), $distmeta->{'X_deep'}, 179 "->custom(x) [is a deep clone]" 180); 181 182my $with_features = $meta->effective_prereqs([ qw(domination) ]); 183 184is_deeply( 185 $with_features->as_string_hash, 186 { 187 develop => { requires => { 'Genius::Evil' => '1.234' } }, 188 runtime => { 189 requires => { 190 'perl' => '5.006', 191 'Config' => '0', 192 'Cwd' => '0', 193 'Data::Dumper' => '0', 194 'ExtUtils::Install' => '0', 195 'File::Basename' => '0', 196 'File::Compare' => '0', 197 'File::Copy' => '0', 198 'File::Find' => '0', 199 'File::Path' => '0', 200 'File::Spec' => '0', 201 'IO::File' => '0', 202 'Machine::Weather' => '2.0', 203 }, 204 recommends => { 205 'Archive::Tar' => '1.00', 206 'ExtUtils::Install' => '0.3', 207 'ExtUtils::ParseXS' => '2.02', 208 'Pod::Text' => '0', 209 'YAML' => '0.35', 210 }, 211 }, 212 build => { 213 requires => { 214 'Test::More' => '0', 215 }, 216 } 217 }, 218 "->effective_prereqs([ qw(domination) ])" 219); 220 221my $chk_feature = sub { 222 my $feature = shift; 223 224 isa_ok($feature, 'CPAN::Meta::Feature'); 225 226 is($feature->identifier, 'domination', '$feature->identifier'); 227 is($feature->description, 'Take over the world', '$feature->description'); 228 229 is_deeply( 230 $feature->prereqs->as_string_hash, 231 { 232 develop => { requires => { 'Genius::Evil' => '1.234' } }, 233 runtime => { requires => { 'Machine::Weather' => '2.0' } }, 234 }, 235 '$feature->prereqs', 236 ); 237}; 238 239my @features = $meta->features; 240is(@features, 1, "we got one feature"); 241$chk_feature->($features[0]); 242 243$chk_feature->( $meta->feature('domination') ); 244 245 246sub read_file { 247 my $filename = shift; 248 open my $fh, '<', $filename; 249 local $/; 250 my $string = <$fh>; 251 $string =~ s/\$VERSION/$CPAN::Meta::VERSION/g; 252 $string; 253} 254 255sub clean_backends { 256 my $string = shift; 257 $string =~ s{"?generated_by.*}{}; 258 $string =~ s{"?x_serialization_backend.*}{}; 259 return $string; 260} 261 262is( 263 clean_backends($meta->as_string()), 264 clean_backends(read_file('t/data-valid/META-2.json')), 265 'as_string with no arguments defaults to version 2 and JSON', 266); 267 268is( 269 clean_backends($meta->as_string({ version => 2 })), 270 clean_backends(read_file('t/data-valid/META-2.json')), 271 'as_string using version 2 defaults to JSON', 272); 273 274is( 275 clean_backends($meta->as_string({ version => 1.4 })), 276 clean_backends(read_file('t/data-valid/META-1_4.yml')), 277 'as_string using version 1.4 defaults to YAML', 278); 279 280done_testing; 281# vim: ts=2 sts=2 sw=2 et : 282