The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Changes 015
MANIFEST 22
META.json 1114
META.yml 1012
Makefile.PL 34
README 35
cpanfile 03
dist.ini 05
lib/CPAN/Meta/Converter.pm 22
lib/CPAN/Meta/Feature.pm 22
lib/CPAN/Meta/History.pm 22
lib/CPAN/Meta/Merge.pm 535
lib/CPAN/Meta/Prereqs.pm 22
lib/CPAN/Meta/Spec.pm 22
lib/CPAN/Meta/Validator.pm 22
lib/CPAN/Meta.pm 610
t/00-report-prereqs.dd 14
t/merge.t 11
t/optional_feature-merge.t 0142
t/strings.t 630
xt/author/00-compile.t 45
xt/author/pod-spell.t 66
22 files changed (This is a version diff) 127275
@@ -1,11 +1,26 @@
 Revision history for CPAN-Meta
 
+2.143240  2014-11-20 10:26:30-05:00 America/New_York
+
+  [FIXED]
+
+  - Give correct path in nested merges such as resources
+
+  - Removed strings test that should have been removed when
+    CPAN::Meta::Requirements was removed to a separate dist
+
 2.142690  2014-09-26 11:06:34-04:00 America/New_York
 
+  [FIXED]
+
+  - Fixed use of incorrect method in CPAN::Meta::Merge implementation
+
   [DOCUMENTED]
 
   - Clarified that no_index is a list of exclusions, and that indexers
     should generally exclude 'inc', 'xt' and 't' as well.
+  - CPAN::Meta::History::Meta_1_0 through 1_4 are added as a permanent
+    record of 1.x versions of the metaspec
 
 2.142060  2014-07-25 13:30:06-04:00 America/New_York
 
@@ -1,4 +1,4 @@
-# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.020.
+# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.025.
 CONTRIBUTING
 Changes
 LICENSE
@@ -88,12 +88,12 @@ t/load-bad.t
 t/merge.t
 t/meta-obj.t
 t/no-index.t
+t/optional_feature-merge.t
 t/prereqs-finalize.t
 t/prereqs-merge.t
 t/prereqs.t
 t/repository.t
 t/save-load.t
-t/strings.t
 t/validator.t
 xt/author/00-compile.t
 xt/author/critic.t
@@ -5,7 +5,7 @@
       "Ricardo Signes <rjbs@cpan.org>"
    ],
    "dynamic_config" : 0,
-   "generated_by" : "Dist::Zilla version 5.020, CPAN::Meta::Converter version 2.140640",
+   "generated_by" : "Dist::Zilla version 5.025, CPAN::Meta::Converter version 2.142690",
    "license" : [
       "perl_5"
    ],
@@ -29,12 +29,14 @@
    "prereqs" : {
       "configure" : {
          "requires" : {
-            "ExtUtils::MakeMaker" : "6.17"
+            "ExtUtils::MakeMaker" : "6.17",
+            "perl" : "5.006"
          }
       },
       "develop" : {
          "requires" : {
             "Dist::Zilla" : "5",
+            "Dist::Zilla::Plugin::Encoding" : "0",
             "Dist::Zilla::Plugin::MakeMaker" : "0",
             "Dist::Zilla::Plugin::MakeMaker::Highlander" : "0.003",
             "Dist::Zilla::Plugin::OnlyCorePrereqs" : "0.014",
@@ -80,6 +82,7 @@
             "IO::Dir" : "0",
             "Test::More" : "0.88",
             "overload" : "0",
+            "perl" : "5.008",
             "utf8" : "0"
          }
       }
@@ -87,35 +90,35 @@
    "provides" : {
       "CPAN::Meta" : {
          "file" : "lib/CPAN/Meta.pm",
-         "version" : "2.142690"
+         "version" : "2.143240"
       },
       "CPAN::Meta::Converter" : {
          "file" : "lib/CPAN/Meta/Converter.pm",
-         "version" : "2.142690"
+         "version" : "2.143240"
       },
       "CPAN::Meta::Feature" : {
          "file" : "lib/CPAN/Meta/Feature.pm",
-         "version" : "2.142690"
+         "version" : "2.143240"
       },
       "CPAN::Meta::History" : {
          "file" : "lib/CPAN/Meta/History.pm",
-         "version" : "2.142690"
+         "version" : "2.143240"
       },
       "CPAN::Meta::Merge" : {
          "file" : "lib/CPAN/Meta/Merge.pm",
-         "version" : "2.142690"
+         "version" : "2.143240"
       },
       "CPAN::Meta::Prereqs" : {
          "file" : "lib/CPAN/Meta/Prereqs.pm",
-         "version" : "2.142690"
+         "version" : "2.143240"
       },
       "CPAN::Meta::Spec" : {
          "file" : "lib/CPAN/Meta/Spec.pm",
-         "version" : "2.142690"
+         "version" : "2.143240"
       },
       "CPAN::Meta::Validator" : {
          "file" : "lib/CPAN/Meta/Validator.pm",
-         "version" : "2.142690"
+         "version" : "2.143240"
       }
    },
    "release_status" : "stable",
@@ -130,7 +133,7 @@
          "web" : "https://github.com/Perl-Toolchain-Gang/CPAN-Meta"
       }
    },
-   "version" : "2.142690",
+   "version" : "2.143240",
    "x_authority" : "cpan:DAGOLDEN",
    "x_contributors" : [
       "Ansgar Burchardt <ansgar@cpan.org>",
@@ -12,11 +12,13 @@ build_requires:
   IO::Dir: '0'
   Test::More: '0.88'
   overload: '0'
+  perl: '5.008'
   utf8: '0'
 configure_requires:
   ExtUtils::MakeMaker: '6.17'
+  perl: '5.006'
 dynamic_config: 0
-generated_by: 'Dist::Zilla version 5.020, CPAN::Meta::Converter version 2.140640'
+generated_by: 'Dist::Zilla version 5.025, CPAN::Meta::Converter version 2.142690'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -34,28 +36,28 @@ no_index:
 provides:
   CPAN::Meta:
     file: lib/CPAN/Meta.pm
-    version: '2.142690'
+    version: '2.143240'
   CPAN::Meta::Converter:
     file: lib/CPAN/Meta/Converter.pm
-    version: '2.142690'
+    version: '2.143240'
   CPAN::Meta::Feature:
     file: lib/CPAN/Meta/Feature.pm
-    version: '2.142690'
+    version: '2.143240'
   CPAN::Meta::History:
     file: lib/CPAN/Meta/History.pm
-    version: '2.142690'
+    version: '2.143240'
   CPAN::Meta::Merge:
     file: lib/CPAN/Meta/Merge.pm
-    version: '2.142690'
+    version: '2.143240'
   CPAN::Meta::Prereqs:
     file: lib/CPAN/Meta/Prereqs.pm
-    version: '2.142690'
+    version: '2.143240'
   CPAN::Meta::Spec:
     file: lib/CPAN/Meta/Spec.pm
-    version: '2.142690'
+    version: '2.143240'
   CPAN::Meta::Validator:
     file: lib/CPAN/Meta/Validator.pm
-    version: '2.142690'
+    version: '2.143240'
 requires:
   CPAN::Meta::Requirements: '2.121'
   CPAN::Meta::YAML: '0.008'
@@ -71,7 +73,7 @@ resources:
   bugtracker: https://github.com/Perl-Toolchain-Gang/CPAN-Meta/issues
   homepage: https://github.com/Perl-Toolchain-Gang/CPAN-Meta
   repository: https://github.com/Perl-Toolchain-Gang/CPAN-Meta.git
-version: '2.142690'
+version: '2.143240'
 x_authority: cpan:DAGOLDEN
 x_contributors:
   - 'Ansgar Burchardt <ansgar@cpan.org>'
@@ -1,5 +1,5 @@
 
-# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.020.
+# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.025.
 use strict;
 use warnings;
 
@@ -18,6 +18,7 @@ my %WriteMakefileArgs = (
   "DISTNAME" => "CPAN-Meta",
   "EXE_FILES" => [],
   "LICENSE" => "perl",
+  "MIN_PERL_VERSION" => "5.008",
   "NAME" => "CPAN::Meta",
   "PREREQ_PM" => {
     "CPAN::Meta::Requirements" => "2.121",
@@ -41,7 +42,7 @@ my %WriteMakefileArgs = (
     "overload" => 0,
     "utf8" => 0
   },
-  "VERSION" => "2.142690",
+  "VERSION" => "2.143240",
   "test" => {
     "TESTS" => "t/*.t"
   }
@@ -53,7 +54,7 @@ my %FallbackPrereqs = (
   "CPAN::Meta::YAML" => "0.008",
   "Carp" => 0,
   "Data::Dumper" => 0,
-  "ExtUtils::MakeMaker" => 0,
+  "ExtUtils::MakeMaker" => "6.17",
   "File::Basename" => 0,
   "File::Spec" => 0,
   "File::Temp" => "0.20",
@@ -2,7 +2,7 @@ NAME
     CPAN::Meta - the distribution metadata for a CPAN dist
 
 VERSION
-    version 2.142690
+    version 2.143240
 
 SYNOPSIS
         use v5.10;
@@ -146,7 +146,8 @@ METHODS
 
     This method returns true if the given file should be indexed. It decides
     this by checking the "file" and "directory" keys in the "no_index"
-    property of the distmeta structure.
+    property of the distmeta structure. Note that neither the version format
+    nor "release_status" are considered.
 
     $filename should be given in unix format.
 
@@ -155,7 +156,8 @@ METHODS
 
     This method returns true if the given package should be indexed. It
     decides this by checking the "package" and "namespace" keys in the
-    "no_index" property of the distmeta structure.
+    "no_index" property of the distmeta structure. Note that neither the
+    version format nor "release_status" are considered.
 
   features
       my @feature_objects = $meta->features;
@@ -18,6 +18,7 @@ on 'test' => sub {
   requires "IO::Dir" => "0";
   requires "Test::More" => "0.88";
   requires "overload" => "0";
+  requires "perl" => "5.008";
   requires "utf8" => "0";
 };
 
@@ -27,10 +28,12 @@ on 'test' => sub {
 
 on 'configure' => sub {
   requires "ExtUtils::MakeMaker" => "6.17";
+  requires "perl" => "5.006";
 };
 
 on 'develop' => sub {
   requires "Dist::Zilla" => "5";
+  requires "Dist::Zilla::Plugin::Encoding" => "0";
   requires "Dist::Zilla::Plugin::MakeMaker" => "0";
   requires "Dist::Zilla::Plugin::MakeMaker::Highlander" => "0.003";
   requires "Dist::Zilla::Plugin::OnlyCorePrereqs" => "0.014";
@@ -5,6 +5,11 @@ license = Perl_5
 copyright_holder = David Golden and Ricardo Signes
 copyright_year   = 2010
 
+; set these to bytes to make MinimumPerl skip them
+[Encoding]
+encoding = bytes
+match = ^t/data-
+
 [@DAGOLDEN]
 :version = 0.070
 -remove = MakeMaker
@@ -3,7 +3,7 @@ use strict;
 use warnings;
 package CPAN::Meta::Converter;
 # VERSION
-$CPAN::Meta::Converter::VERSION = '2.142690';
+$CPAN::Meta::Converter::VERSION = '2.143240';
 #pod =head1 SYNOPSIS
 #pod
 #pod   my $struct = decode_json_file('META.json');
@@ -1494,7 +1494,7 @@ CPAN::Meta::Converter - Convert CPAN distribution metadata structures
 
 =head1 VERSION
 
-version 2.142690
+version 2.143240
 
 =head1 SYNOPSIS
 
@@ -3,7 +3,7 @@ use strict;
 use warnings;
 package CPAN::Meta::Feature;
 # VERSION
-$CPAN::Meta::Feature::VERSION = '2.142690';
+$CPAN::Meta::Feature::VERSION = '2.143240';
 use CPAN::Meta::Prereqs;
 
 #pod =head1 DESCRIPTION
@@ -78,7 +78,7 @@ CPAN::Meta::Feature - an optional feature provided by a CPAN distribution
 
 =head1 VERSION
 
-version 2.142690
+version 2.143240
 
 =head1 DESCRIPTION
 
@@ -4,7 +4,7 @@ use strict;
 use warnings;
 package CPAN::Meta::History;
 # VERSION
-$CPAN::Meta::History::VERSION = '2.142690';
+$CPAN::Meta::History::VERSION = '2.143240';
 1;
 
 # ABSTRACT: history of CPAN Meta Spec changes
@@ -21,7 +21,7 @@ CPAN::Meta::History - history of CPAN Meta Spec changes
 
 =head1 VERSION
 
-version 2.142690
+version 2.143240
 
 =head1 DESCRIPTION
 
@@ -3,14 +3,14 @@ use warnings;
 
 package CPAN::Meta::Merge;
 # VERSION
-$CPAN::Meta::Merge::VERSION = '2.142690';
+$CPAN::Meta::Merge::VERSION = '2.143240';
 use Carp qw/croak/;
 use Scalar::Util qw/blessed/;
 use CPAN::Meta::Converter;
 
 sub _identical {
   my ($left, $right, $path) = @_;
-  croak "Can't merge attribute " . join '.', @{$path} unless $left eq $right;
+  croak sprintf "Can't merge attribute %s: '%s' does not equal '%s'", join('.', @{$path}), $left, $right unless $left eq $right;
   return $left;
 }
 
@@ -73,6 +73,36 @@ sub _improvize {
   croak sprintf "Can't merge '%s'", join '.', @{$path};
 }
 
+sub _optional_features {
+  my ($left, $right, $path) = @_;
+
+  for my $key (keys %{$right}) {
+    if (not exists $left->{$key}) {
+      $left->{$key} = $right->{$key};
+    }
+    else {
+      for my $subkey (keys %{ $right->{$key} }) {
+        next if $subkey eq 'prereqs';
+        if (not exists $left->{$key}{$subkey}) {
+          $left->{$key}{$subkey} = $right->{$key}{$subkey};
+        }
+        else {
+          Carp::croak "Cannot merge two optional_features named '$key' with different '$subkey' values"
+            if do { no warnings 'uninitialized'; $left->{$key}{$subkey} ne $right->{$key}{$subkey} };
+        }
+      }
+
+      require CPAN::Meta::Prereqs;
+      $left->{$key}{prereqs} =
+        CPAN::Meta::Prereqs->new($left->{$key}{prereqs})
+          ->with_merged_prereqs(CPAN::Meta::Prereqs->new($right->{$key}{prereqs}))
+          ->as_string_hash;
+    }
+  }
+  return $left;
+}
+
+
 my %default = (
   abstract       => \&_identical,
   author         => \&_set_addition,
@@ -95,7 +125,7 @@ my %default = (
   description       => \&_identical,
   keywords          => \&_set_addition,
   no_index          => { map { ($_ => \&_set_addition) } qw/file directory package namespace/ },
-  optional_features => \&_uniq_map,
+  optional_features => \&_optional_features,
   prereqs           => sub {
     require CPAN::Meta::Prereqs;
     my ($left, $right) = map { CPAN::Meta::Prereqs->new($_) } @_[0,1];
@@ -150,7 +180,7 @@ sub _coerce_mapping {
       my $mapping = _coerce_mapping($value, [ @{$map_path}, $key ]);
       $ret{$key} = sub {
         my ($left, $right, $path) = @_;
-        return _merge($left, $right, $mapping, [ @{$path}, $key ]);
+        return _merge($left, $right, $mapping, [ @{$path} ]);
       };
     }
     elsif ($coderef_for{$value}) {
@@ -200,7 +230,7 @@ CPAN::Meta::Merge - Merging CPAN Meta fragments
 
 =head1 VERSION
 
-version 2.142690
+version 2.143240
 
 =head1 SYNOPSIS
 
@@ -3,7 +3,7 @@ use strict;
 use warnings;
 package CPAN::Meta::Prereqs;
 # VERSION
-$CPAN::Meta::Prereqs::VERSION = '2.142690';
+$CPAN::Meta::Prereqs::VERSION = '2.143240';
 #pod =head1 DESCRIPTION
 #pod
 #pod A CPAN::Meta::Prereqs object represents the prerequisites for a CPAN
@@ -286,7 +286,7 @@ CPAN::Meta::Prereqs - a set of distribution prerequisites by phase and type
 
 =head1 VERSION
 
-version 2.142690
+version 2.143240
 
 =head1 DESCRIPTION
 
@@ -8,7 +8,7 @@ use strict;
 use warnings;
 package CPAN::Meta::Spec;
 # VERSION
-$CPAN::Meta::Spec::VERSION = '2.142690';
+$CPAN::Meta::Spec::VERSION = '2.143240';
 1;
 
 # ABSTRACT: specification for CPAN distribution metadata
@@ -28,7 +28,7 @@ CPAN::Meta::Spec - specification for CPAN distribution metadata
 
 =head1 VERSION
 
-version 2.142690
+version 2.143240
 
 =head1 SYNOPSIS
 
@@ -3,7 +3,7 @@ use strict;
 use warnings;
 package CPAN::Meta::Validator;
 # VERSION
-$CPAN::Meta::Validator::VERSION = '2.142690';
+$CPAN::Meta::Validator::VERSION = '2.143240';
 #pod =head1 SYNOPSIS
 #pod
 #pod   my $struct = decode_json_file('META.json');
@@ -997,7 +997,7 @@ CPAN::Meta::Validator - validate CPAN distribution metadata structures
 
 =head1 VERSION
 
-version 2.142690
+version 2.143240
 
 =head1 SYNOPSIS
 
@@ -3,7 +3,7 @@ use strict;
 use warnings;
 package CPAN::Meta;
 # VERSION
-$CPAN::Meta::VERSION = '2.142690';
+$CPAN::Meta::VERSION = '2.143240';
 #pod =head1 SYNOPSIS
 #pod
 #pod     use v5.10;
@@ -465,7 +465,8 @@ sub effective_prereqs {
 #pod
 #pod This method returns true if the given file should be indexed.  It decides this
 #pod by checking the C<file> and C<directory> keys in the C<no_index> property of
-#pod the distmeta structure.
+#pod the distmeta structure. Note that neither the version format nor
+#pod C<release_status> are considered.
 #pod
 #pod C<$filename> should be given in unix format.
 #pod
@@ -492,7 +493,8 @@ sub should_index_file {
 #pod
 #pod This method returns true if the given package should be indexed.  It decides
 #pod this by checking the C<package> and C<namespace> keys in the C<no_index>
-#pod property of the distmeta structure.
+#pod property of the distmeta structure. Note that neither the version format nor
+#pod C<release_status> are considered.
 #pod
 #pod =cut
 
@@ -641,7 +643,7 @@ CPAN::Meta - the distribution metadata for a CPAN dist
 
 =head1 VERSION
 
-version 2.142690
+version 2.143240
 
 =head1 SYNOPSIS
 
@@ -799,7 +801,8 @@ distribution's core prereqs before the CPAN::Meta::Prereqs object is returned.
 
 This method returns true if the given file should be indexed.  It decides this
 by checking the C<file> and C<directory> keys in the C<no_index> property of
-the distmeta structure.
+the distmeta structure. Note that neither the version format nor
+C<release_status> are considered.
 
 C<$filename> should be given in unix format.
 
@@ -809,7 +812,8 @@ C<$filename> should be given in unix format.
 
 This method returns true if the given package should be indexed.  It decides
 this by checking the C<package> and C<namespace> keys in the C<no_index>
-property of the distmeta structure.
+property of the distmeta structure. Note that neither the version format nor
+C<release_status> are considered.
 
 =head2 features
 
@@ -1,12 +1,14 @@
 do { my $x = {
        'configure' => {
                         'requires' => {
-                                        'ExtUtils::MakeMaker' => '6.17'
+                                        'ExtUtils::MakeMaker' => '6.17',
+                                        'perl' => '5.006'
                                       }
                       },
        'develop' => {
                       'requires' => {
                                       'Dist::Zilla' => '5',
+                                      'Dist::Zilla::Plugin::Encoding' => '0',
                                       'Dist::Zilla::Plugin::MakeMaker' => '0',
                                       'Dist::Zilla::Plugin::MakeMaker::Highlander' => '0.003',
                                       'Dist::Zilla::Plugin::OnlyCorePrereqs' => '0.014',
@@ -52,6 +54,7 @@ do { my $x = {
                                    'IO::Dir' => '0',
                                    'Test::More' => '0.88',
                                    'overload' => '0',
+                                   'perl' => '5.008',
                                    'utf8' => '0'
                                  }
                  }
@@ -110,7 +110,7 @@ is_deeply($first_result, \%first_expected, 'First result is as expected');
 is_deeply($merger->merge(\%base, { abstract => 'This is a test' }), \%base, 'Can merge in identical abstract');
 my $failure = eval { $merger->merge(\%base, { abstract => 'And now for something else' }) };
 is($failure, undef, 'Trying to merge different author gives an exception');
-like $@, qr/^Can't merge attribute abstract /, 'Exception looks right';
+like $@, qr/^Can't merge attribute abstract/, 'Exception looks right';
 
 my $failure2 = eval { $merger->merge(\%base, { provides => { Baz => { file => 'Baz.pm' } } }) };
 is($failure2, undef, 'Trying to merge different author gives an exception');
@@ -0,0 +1,142 @@
+use strict;
+use warnings;
+# vim: set ts=4 sw=4 noet nolist :
+
+use Test::More;
+use CPAN::Meta;
+use CPAN::Meta::Merge;
+
+my %base = (
+	abstract => 'This is a test',
+	author => ['A.U. Thor'],
+	generated_by => 'Myself',
+	license => [ 'perl_5' ],
+	resources => {
+		license => [ 'http://dev.perl.org/licenses/' ],
+	},
+	prereqs => {
+		runtime => {
+			requires => {
+				Foo => '0',
+			},
+		},
+	},
+	dynamic_config => 0,
+	provides => {
+		Baz => {
+			file => 'lib/Baz.pm',
+		},
+	},
+	'meta-spec' => {
+		url => "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
+		version => 2,
+	},
+);
+
+my $fragment1 = {
+	'optional_features' => {
+		'FeatureName' => {
+			'description' => 'desc',
+			'x_default' => 1,
+			'prereqs' => { 'runtime' => { 'requires' => { 'A' => '0' } } }
+		}
+	}
+};
+my $fragment2 = {
+	'optional_features' => {
+		'FeatureName' => {
+			'description' => 'desc',
+			'prereqs' => { 'test' => { 'requires' => { 'B' => '0' } } }
+		}
+	}
+};
+
+my $merger = CPAN::Meta::Merge->new(default_version => "2");
+my $meta1 = $merger->merge(\%base, $fragment1);
+
+is_deeply(
+	$meta1,
+	{
+		%base,
+		%$fragment1,
+	},
+	'merged first optional_feature fragment into base',
+);
+
+my $meta2 = $merger->merge($meta1, $fragment2);
+
+is_deeply(
+	$meta2,
+	{
+		%base,
+		'optional_features' => {
+			'FeatureName' => {
+				'description' => 'desc',
+				'x_default' => 1,
+				'prereqs' => {
+					'runtime' => { 'requires' => { 'A' => '0' } },
+					'test' => { 'requires' => { 'B' => '0' } },
+				}
+			}
+		}
+	},
+	'merged second optional_feature fragment into the first',
+);
+
+my $fragment3 = {
+	'optional_features' => {
+		'FeatureName' => {
+			'description' => 'other desc',
+			'prereqs' => { 'test' => { 'requires' => { 'B' => '0' } } }
+		}
+	}
+};
+
+my $result = eval { $merger->merge($meta1, $fragment3) };
+is($result, undef, 'Trying to merge optional_features with same feature name and different descriptions gives an exception');
+like $@, qr/^Cannot merge two optional_features named 'FeatureName' with different 'description' values/, 'Exception looks right';
+
+my $fragment4 = {
+	'optional_features' => {
+		'FeatureName' => {
+			'description' => 'desc',
+			'x_default' => 0,
+			'prereqs' => { 'test' => { 'requires' => { 'B' => '0' } } }
+		}
+	}
+};
+
+$result = eval { $merger->merge($meta1, $fragment4) };
+is($result, undef, 'Trying to merge optional_features with same feature name and differences in other keys gives an exception');
+like $@, qr/^Cannot merge two optional_features named 'FeatureName' with different 'x_default' values/, 'Exception looks right';
+
+my $fragment5 = {
+	'optional_features' => {
+		'Another FeatureName' => {
+			'description' => 'desc',
+			'prereqs' => { 'test' => { 'requires' => { 'B' => '0' } } }
+		}
+	}
+};
+
+my $meta5 = $merger->merge($meta1, $fragment5);
+is_deeply(
+	$meta5,
+	{
+		%base,
+		'optional_features' => {
+			'FeatureName' => {
+				'description' => 'desc',
+				'x_default' => 1,
+				'prereqs' => { 'runtime' => { 'requires' => { 'A' => '0' } } },
+			},
+			'Another FeatureName' => {
+				'description' => 'desc',
+				'prereqs' => { 'test' => { 'requires' => { 'B' => '0' } } },
+			}
+		}
+	},
+	'can merge optional_features with different names without collisions',
+);
+
+done_testing;
@@ -1,63 +0,0 @@
-use strict;
-use warnings;
-use Test::More 0.88;
-
-sub dies_ok (&@) {
-  my ($code, $qr, $comment) = @_;
-
-  my $lived = eval { $code->(); 1 };
-
-  if ($lived) {
-    fail("$comment: did not die");
-  } else {
-    like($@, $qr, $comment);
-  }
-}
-
-use CPAN::Meta::Requirements;
-
-my $req = CPAN::Meta::Requirements->new;
-
-# Test ==
-$req->add_string_requirement('Foo::Bar', '== 1.3');
-ok($req->accepts_module('Foo::Bar' => '1.3'), 'exact version (==)');
-ok(!$req->accepts_module('Foo::Bar' => '1.2'), 'lower version (==)');
-ok(!$req->accepts_module('Foo::Bar' => '1.4'), 'higher version (==)');
-
-# Test !=
-$req->add_string_requirement('Foo::Baz', '!= 1.3');
-ok(!$req->accepts_module('Foo::Baz' => '1.3'), 'exact version (!=)');
-ok($req->accepts_module('Foo::Baz' => '1.2'), 'lower version (!=)');
-ok($req->accepts_module('Foo::Baz' => '1.4'), 'higher version (!=)');
-
-# Test >=
-$req->add_string_requirement('Foo::Gorch', '>= 1.3');
-ok($req->accepts_module('Foo::Gorch' => '1.3'), 'exact version (>=)');
-ok(!$req->accepts_module('Foo::Gorch' => '1.2'), 'lower version (>=)');
-ok($req->accepts_module('Foo::Gorch' => '1.4'), 'higher version (>=)');
-
-# Test <=
-$req->add_string_requirement('Foo::Graz', '<= 1.3');
-ok($req->accepts_module('Foo::Graz' => '1.3'), 'exact version (<=)');
-ok($req->accepts_module('Foo::Graz' => '1.2'), 'lower version (<=)');
-ok(!$req->accepts_module('Foo::Graz' => '1.4'), 'higher version (<=)');
-
-# Test ""
-$req->add_string_requirement('Foo::Blurb', '>= 1.3');
-ok($req->accepts_module('Foo::Blurb' => '1.3'), 'exact version (>=)');
-ok(!$req->accepts_module('Foo::Blurb' => '1.2'), 'lower version (>=)');
-ok($req->accepts_module('Foo::Blurb' => '1.4'), 'higher version (>=)');
-
-# Test multiple requirements
-$req->add_string_requirement('A::Tribe::Called', '>= 1.3, <= 2.0, != 1.6');
-ok($req->accepts_module('A::Tribe::Called' => '1.5'), 'middle version (>=, <=, !)');
-ok(!$req->accepts_module('A::Tribe::Called' => '1.2'), 'lower version (>=, <=, !)');
-ok(!$req->accepts_module('A::Tribe::Called' => '2.1'), 'higher version (>=, <=, !)');
-ok(!$req->accepts_module('A::Tribe::Called' => '1.6'), 'excluded version (>=, <=, !)');
-
-# Test fatal errors
-dies_ok { $req->add_string_requirement('Foo::Bar', undef) }
-  qr/No requirement string provided/,
-  "die without a requirement string";
-
-done_testing;
@@ -2,11 +2,11 @@ use 5.006;
 use strict;
 use warnings;
 
-# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.046
-
-use Test::More  tests => 8 + ($ENV{AUTHOR_TESTING} ? 1 : 0);
+# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.051
 
+use Test::More;
 
+plan tests => 8 + ($ENV{AUTHOR_TESTING} ? 1 : 0);
 
 my @module_files = (
     'CPAN/Meta.pm',
@@ -55,6 +55,7 @@ for my $lib (@module_files)
 
 
 
-is(scalar(@warnings), 0, 'no warnings found') or diag 'got warnings: ', explain \@warnings if $ENV{AUTHOR_TESTING};
+is(scalar(@warnings), 0, 'no warnings found')
+    or diag 'got warnings: ', ( Test::More->can('explain') ? Test::More::explain(\@warnings) : join("\n", '', @warnings) ) if $ENV{AUTHOR_TESTING};
 
 
@@ -92,15 +92,15 @@ randys
 lib
 CPAN
 Meta
+Validator
 History
+Meta_1_3
+Converter
 Meta_1_0
+Meta_1_2
+Prereqs
 Spec
-Meta_1_1
 Meta_1_4
-Prereqs
-Meta_1_2
+Meta_1_1
 Feature
 Merge
-Validator
-Meta_1_3
-Converter