1use strict; 2use warnings; 3 4use Test::More; 5use CPAN::Meta; 6use CPAN::Meta::Merge; 7 8delete $ENV{PERL_YAML_BACKEND}; 9delete $ENV{PERL_JSON_BACKEND}; 10delete $ENV{CPAN_META_JSON_BACKEND}; 11delete $ENV{CPAN_META_JSON_DECODER}; 12 13my %base = ( 14 abstract => 'This is a test', 15 author => ['A.U. Thor'], 16 generated_by => 'Myself', 17 license => [ 'perl_5' ], 18 resources => { 19 license => [ 'http://dev.perl.org/licenses/' ], 20 }, 21 prereqs => { 22 runtime => { 23 requires => { 24 Foo => '0', 25 }, 26 }, 27 }, 28 dynamic_config => 0, 29 provides => { 30 Baz => { 31 file => 'lib/Baz.pm', 32 }, 33 }, 34 'meta-spec' => { 35 url => "http://search.cpan.org/perldoc?CPAN::Meta::Spec", 36 version => 2, 37 }, 38); 39 40my $fragment1 = { 41 'optional_features' => { 42 'FeatureName' => { 43 'description' => 'desc', 44 'x_default' => 1, 45 'prereqs' => { 'runtime' => { 'requires' => { 'A' => '0' } } } 46 } 47 } 48}; 49my $fragment2 = { 50 'optional_features' => { 51 'FeatureName' => { 52 'description' => 'desc', 53 'prereqs' => { 'test' => { 'requires' => { 'B' => '0' } } } 54 } 55 } 56}; 57 58my $merger = CPAN::Meta::Merge->new(default_version => "2"); 59my $meta1 = $merger->merge(\%base, $fragment1); 60 61is_deeply( 62 $meta1, 63 { 64 %base, 65 %$fragment1, 66 }, 67 'merged first optional_feature fragment into base', 68); 69 70my $meta2 = $merger->merge($meta1, $fragment2); 71 72is_deeply( 73 $meta2, 74 { 75 %base, 76 'optional_features' => { 77 'FeatureName' => { 78 'description' => 'desc', 79 'x_default' => 1, 80 'prereqs' => { 81 'runtime' => { 'requires' => { 'A' => '0' } }, 82 'test' => { 'requires' => { 'B' => '0' } }, 83 } 84 } 85 } 86 }, 87 'merged second optional_feature fragment into the first', 88); 89 90my $fragment3 = { 91 'optional_features' => { 92 'FeatureName' => { 93 'description' => 'other desc', 94 'prereqs' => { 'test' => { 'requires' => { 'B' => '0' } } } 95 } 96 } 97}; 98 99is( eval { $merger->merge($meta1, $fragment3) }, undef, 'Trying to merge optional_features with same feature name and different descriptions gives an exception'); 100like $@, qr/^Cannot merge two optional_features named 'FeatureName' with different 'description' values/, 'Exception looks right'; 101 102my $fragment4 = { 103 'optional_features' => { 104 'FeatureName' => { 105 'description' => 'desc', 106 'x_default' => 0, 107 'prereqs' => { 'test' => { 'requires' => { 'B' => '0' } } } 108 } 109 } 110}; 111 112is( eval { $merger->merge($meta1, $fragment4) }, undef, 'Trying to merge optional_features with same feature name and differences in other keys gives an exception'); 113like $@, qr/^Cannot merge two optional_features named 'FeatureName' with different 'x_default' values/, 'Exception looks right'; 114 115my $fragment5 = { 116 'optional_features' => { 117 'Another FeatureName' => { 118 'description' => 'desc', 119 'prereqs' => { 'test' => { 'requires' => { 'B' => '0' } } } 120 } 121 } 122}; 123 124my $meta5 = $merger->merge($meta1, $fragment5); 125is_deeply( 126 $meta5, 127 { 128 %base, 129 'optional_features' => { 130 'FeatureName' => { 131 'description' => 'desc', 132 'x_default' => 1, 133 'prereqs' => { 'runtime' => { 'requires' => { 'A' => '0' } } }, 134 }, 135 'Another FeatureName' => { 136 'description' => 'desc', 137 'prereqs' => { 'test' => { 'requires' => { 'B' => '0' } } }, 138 } 139 } 140 }, 141 'can merge optional_features with different names without collisions', 142); 143 144done_testing; 145# vim: ts=4 sts=4 sw=4 noet : 146