summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSteffen Mueller <smueller@cpan.org>2009-05-17 11:55:50 +0200
committerSteffen Mueller <smueller@cpan.org>2009-05-17 11:55:50 +0200
commitde044c3605bd12a0b679b024ec9c16b44093c54b (patch)
tree4994a58d2c64657aa2dcc3f3b8d502f7c1d1fc23 /lib
parent19e87f221220123fd05380fca766d035586f60bf (diff)
downloadperl-de044c3605bd12a0b679b024ec9c16b44093c54b.tar.gz
Upgrade to Parse::CPAN::Meta 1.38
Diffstat (limited to 'lib')
-rw-r--r--lib/Parse/CPAN/Meta.pm862
-rw-r--r--lib/Parse/CPAN/Meta/Changes8
-rw-r--r--lib/Parse/CPAN/Meta/t/02_basic.t15
-rw-r--r--lib/Parse/CPAN/Meta/t/03_regression.t339
-rw-r--r--lib/Parse/CPAN/Meta/t/05_export.t29
-rw-r--r--lib/Parse/CPAN/Meta/t/11_meta_yml.t139
-rw-r--r--lib/Parse/CPAN/Meta/t/12_plagger.t4
-rw-r--r--lib/Parse/CPAN/Meta/t/13_perl_smith.t2
-rw-r--r--lib/Parse/CPAN/Meta/t/14_yaml_org.t2
-rw-r--r--lib/Parse/CPAN/Meta/t/15_multibyte.t3
-rw-r--r--lib/Parse/CPAN/Meta/t/17_toolbar.t1
-rw-r--r--lib/Parse/CPAN/Meta/t/18_tap.t90
-rw-r--r--lib/Parse/CPAN/Meta/t/19_errors.t43
-rw-r--r--lib/Parse/CPAN/Meta/t/21_bom.t39
-rw-r--r--lib/Parse/CPAN/Meta/t/data/Spreadsheet-Read.yml61
15 files changed, 1166 insertions, 471 deletions
diff --git a/lib/Parse/CPAN/Meta.pm b/lib/Parse/CPAN/Meta.pm
index afbb587bfd..d65d7bb59f 100644
--- a/lib/Parse/CPAN/Meta.pm
+++ b/lib/Parse/CPAN/Meta.pm
@@ -1,425 +1,437 @@
-package Parse::CPAN::Meta;
-
-use strict;
-use Carp 'croak';
-BEGIN {
- require 5.004;
- require Exporter;
- $Parse::CPAN::Meta::VERSION = '0.05';
- @Parse::CPAN::Meta::ISA = qw{ Exporter };
- @Parse::CPAN::Meta::EXPORT_OK = qw{ Load LoadFile };
-}
-
-# Prototypes
-sub LoadFile ($);
-sub Load ($);
-sub _scalar ($$$);
-sub _array ($$$);
-sub _hash ($$$);
-
-# Printable characters for escapes
-my %UNESCAPES = (
- z => "\x00", a => "\x07", t => "\x09",
- n => "\x0a", v => "\x0b", f => "\x0c",
- r => "\x0d", e => "\x1b", '\\' => '\\',
-);
-
-
-my %BOM = (
- "\357\273\277" => 'UTF-8',
- "\376\377" => 'UTF-16BE',
- "\377\376" => 'UTF-16LE',
- "\0\0\376\377" => 'UTF-32BE',
- "\377\376\0\0" => 'UTF-32LE'
-);
-
-sub BOM_MIN_LENGTH () { 2 }
-sub BOM_MAX_LENGTH () { 4 }
-sub HAVE_UTF8 () { $] >= 5.007003 }
-
-BEGIN { require utf8 if HAVE_UTF8 }
-
-
-#####################################################################
-# Implementation
-
-# Create an object from a file
-sub LoadFile ($) {
- # Check the file
- my $file = shift;
- croak('You did not specify a file name') unless $file;
- croak( "File '$file' does not exist" ) unless -e $file;
- croak( "'$file' is a directory, not a file" ) unless -f _;
- croak( "Insufficient permissions to read '$file'" ) unless -r _;
-
- # Slurp in the file
- local $/ = undef;
- open( CFG, $file ) or croak("Failed to open file '$file': $!");
- my $yaml = <CFG>;
- close CFG or croak("Failed to close file '$file': $!");
-
- # Hand off to the actual parser
- Load( $yaml );
-}
-
-# Parse a document from a string.
-# Doing checks on $_[0] prevents us having to do a string copy.
-sub Load ($) {
-
- my $str = $_[0];
-
- # Handle special cases
- foreach my $length ( BOM_MIN_LENGTH .. BOM_MAX_LENGTH ) {
- if ( my $enc = $BOM{substr($str, 0, $length)} ) {
- croak("Stream has a non UTF-8 BOM") unless $enc eq 'UTF-8';
- substr($str, 0, $length) = ''; # strip UTF-8 bom if found, we'll just ignore it
- }
- }
-
- if ( HAVE_UTF8 ) {
- utf8::decode($str); # try to decode as utf8
- }
-
- unless ( defined $str ) {
- croak("Did not provide a string to Load");
- }
- return() unless length $str;
- unless ( $str =~ /[\012\015]+$/ ) {
- croak("Stream does not end with newline character");
- }
-
- # Split the file into lines
- my @lines = grep { ! /^\s*(?:\#.*)?$/ }
- split /(?:\015{1,2}\012|\015|\012)/, $str;
-
- # A nibbling parser
- my @documents = ();
- while ( @lines ) {
- # Do we have a document header?
- if ( $lines[0] =~ /^---\s*(?:(.+)\s*)?$/ ) {
- # Handle scalar documents
- shift @lines;
- if ( defined $1 and $1 !~ /^(?:\#.+|\%YAML:[\d\.]+)$/ ) {
- push @documents, _scalar( "$1", [ undef ], \@lines );
- next;
- }
- }
-
- if ( ! @lines or $lines[0] =~ /^---\s*(?:(.+)\s*)?$/ ) {
- # A naked document
- push @documents, undef;
-
- } elsif ( $lines[0] =~ /^\s*\-/ ) {
- # An array at the root
- my $document = [ ];
- push @documents, $document;
- _array( $document, [ 0 ], \@lines );
-
- } elsif ( $lines[0] =~ /^(\s*)\w/ ) {
- # A hash at the root
- my $document = { };
- push @documents, $document;
- _hash( $document, [ length($1) ], \@lines );
-
- } else {
- croak("Parse::CPAN::Meta does not support the line '$lines[0]'");
- }
- }
-
- if ( wantarray ) {
- return @documents;
- } else {
- return $documents[-1];
- }
-}
-
-# Deparse a scalar string to the actual scalar
-sub _scalar ($$$) {
- my $string = shift;
- my $indent = shift;
- my $lines = shift;
-
- # Trim trailing whitespace
- $string =~ s/\s*$//;
-
- # Explitic null/undef
- return undef if $string eq '~';
-
- # Quotes
- if ( $string =~ /^\'(.*?)\'$/ ) {
- return '' unless defined $1;
- my $rv = $1;
- $rv =~ s/\'\'/\'/g;
- return $rv;
- }
- if ( $string =~ /^\"((?:\\.|[^\"])*)\"$/ ) {
- my $str = $1;
- $str =~ s/\\"/"/g;
- $str =~ s/\\([never\\fartz]|x([0-9a-fA-F]{2}))/(length($1)>1)?pack("H2",$2):$UNESCAPES{$1}/gex;
- return $str;
- }
- if ( $string =~ /^[\'\"]/ ) {
- # A quote with folding... we don't support that
- croak("Parse::CPAN::Meta does not support multi-line quoted scalars");
- }
-
- # Null hash and array
- if ( $string eq '{}' ) {
- # Null hash
- return {};
- }
- if ( $string eq '[]' ) {
- # Null array
- return [];
- }
-
- # Regular unquoted string
- return $string unless $string =~ /^[>|]/;
-
- # Error
- croak("Multi-line scalar content missing") unless @$lines;
-
- # Check the indent depth
- $lines->[0] =~ /^(\s*)/;
- $indent->[-1] = length("$1");
- if ( defined $indent->[-2] and $indent->[-1] <= $indent->[-2] ) {
- croak("Illegal line indenting");
- }
-
- # Pull the lines
- my @multiline = ();
- while ( @$lines ) {
- $lines->[0] =~ /^(\s*)/;
- last unless length($1) >= $indent->[-1];
- push @multiline, substr(shift(@$lines), length($1));
- }
-
- my $j = (substr($string, 0, 1) eq '>') ? ' ' : "\n";
- my $t = (substr($string, 1, 1) eq '-') ? '' : "\n";
- return join( $j, @multiline ) . $t;
-}
-
-# Parse an array
-sub _array ($$$) {
- my $array = shift;
- my $indent = shift;
- my $lines = shift;
-
- while ( @$lines ) {
- # Check for a new document
- return 1 if $lines->[0] =~ /^---\s*(?:(.+)\s*)?$/;
-
- # Check the indent level
- $lines->[0] =~ /^(\s*)/;
- if ( length($1) < $indent->[-1] ) {
- return 1;
- } elsif ( length($1) > $indent->[-1] ) {
- croak("Hash line over-indented");
- }
-
- if ( $lines->[0] =~ /^(\s*\-\s+)[^\'\"]\S*\s*:(?:\s+|$)/ ) {
- # Inline nested hash
- my $indent2 = length("$1");
- $lines->[0] =~ s/-/ /;
- push @$array, { };
- _hash( $array->[-1], [ @$indent, $indent2 ], $lines );
-
- } elsif ( $lines->[0] =~ /^\s*\-(\s*)(.+?)\s*$/ ) {
- # Array entry with a value
- shift @$lines;
- push @$array, _scalar( "$2", [ @$indent, undef ], $lines );
-
- } elsif ( $lines->[0] =~ /^\s*\-\s*$/ ) {
- shift @$lines;
- unless ( @$lines ) {
- push @$array, undef;
- return 1;
- }
- if ( $lines->[0] =~ /^(\s*)\-/ ) {
- my $indent2 = length("$1");
- if ( $indent->[-1] == $indent2 ) {
- # Null array entry
- push @$array, undef;
- } else {
- # Naked indenter
- push @$array, [ ];
- _array( $array->[-1], [ @$indent, $indent2 ], $lines );
- }
-
- } elsif ( $lines->[0] =~ /^(\s*)\w/ ) {
- push @$array, { };
- _hash( $array->[-1], [ @$indent, length("$1") ], $lines );
-
- } else {
- croak("Parse::CPAN::Meta does not support the line '$lines->[0]'");
- }
-
- } elsif ( defined $indent->[-2] and $indent->[-1] == $indent->[-2] ) {
- # This is probably a structure like the following...
- # ---
- # foo:
- # - list
- # bar: value
- #
- # ... so lets return and let the hash parser handle it
- return 1;
-
- } else {
- croak("Parse::CPAN::Meta does not support the line '$lines->[0]'");
- }
- }
-
- return 1;
-}
-
-# Parse an array
-sub _hash ($$$) {
- my $hash = shift;
- my $indent = shift;
- my $lines = shift;
-
- while ( @$lines ) {
- # Check for a new document
- return 1 if $lines->[0] =~ /^---\s*(?:(.+)\s*)?$/;
-
- # Check the indent level
- $lines->[0] =~/^(\s*)/;
- if ( length($1) < $indent->[-1] ) {
- return 1;
- } elsif ( length($1) > $indent->[-1] ) {
- croak("Hash line over-indented");
- }
-
- # Get the key
- unless ( $lines->[0] =~ s/^\s*([^\'\"][^\n]*?)\s*:(\s+|$)// ) {
- croak("Bad hash line");
- }
- my $key = $1;
-
- # Do we have a value?
- if ( length $lines->[0] ) {
- # Yes
- $hash->{$key} = _scalar( shift(@$lines), [ @$indent, undef ], $lines );
- next;
- }
-
- # An indent
- shift @$lines;
- unless ( @$lines ) {
- $hash->{$key} = undef;
- return 1;
- }
- if ( $lines->[0] =~ /^(\s*)-/ ) {
- $hash->{$key} = [];
- _array( $hash->{$key}, [ @$indent, length($1) ], $lines );
- } elsif ( $lines->[0] =~ /^(\s*)./ ) {
- my $indent2 = length("$1");
- if ( $indent->[-1] >= $indent2 ) {
- # Null hash entry
- $hash->{$key} = undef;
- } else {
- $hash->{$key} = {};
- _hash( $hash->{$key}, [ @$indent, length($1) ], $lines );
- }
- }
- }
-
- return 1;
-}
-
-1;
-
-__END__
-
-=pod
-
-=head1 NAME
-
-Parse::CPAN::Meta - Parse META.yml and other similar CPAN metadata files
-
-=head1 SYNOPSIS
-
- #############################################
- # In your file
-
- ---
- rootproperty: blah
- section:
- one: two
- three: four
- Foo: Bar
- empty: ~
-
-
-
- #############################################
- # In your program
-
- use Parse::CPAN::Meta;
-
- # Create a YAML file
- my @yaml = Parse::CPAN::Meta::LoadFile( 'Meta.yml' );
-
- # Reading properties
- my $root = $yaml[0]->{rootproperty};
- my $one = $yaml[0]->{section}->{one};
- my $Foo = $yaml[0]->{section}->{Foo};
-
-=head1 DESCRIPTION
-
-B<Parse::CPAN::Meta> is a parser for META.yml files, based on the
-parser half of L<YAML::Tiny>.
-
-It supports a basic subset of the full YAML specification, enough to
-implement parsing of typical META.yml files, and other similarly simple
-YAML files.
-
-If you need something with more power, move up to a full YAML parser such
-as L<YAML>, L<YAML::Syck> or L<YAML::LibYAML>.
-
-Parse::CPAN::Meta provides a very simply API of only two functions, based
-on the YAML functions of the same name. Wherever possible, identical
-calling semantics are used.
-
-All error reporting is done with exceptions (dieing).
-
-=head1 FUNCTIONS
-
-For maintenance clarity, no functions are exported.
-
-=head2 Load( $string )
-
- my @documents = Load( $string );
-
-Parses a string containing a valid YAML stream into a list of Perl data
-structures.
-
-=head2 LoadFile( $file_name )
-
-Reads the YAML stream from a file instead of a string.
-
-=head1 SUPPORT
-
-Bugs should be reported via the CPAN bug tracker at
-
-L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Parse-CPAN-Meta>
-
-=head1 AUTHOR
-
-Adam Kennedy E<lt>adamk@cpan.orgE<gt>
-
-=head1 SEE ALSO
-
-L<YAML::Tiny>, L<YAML>, L<YAML::Syck>
-
-=head1 COPYRIGHT
-
-Copyright 2006 - 2009 Adam Kennedy.
-
-This program is free software; you can redistribute
-it and/or modify it under the same terms as Perl itself.
-
-The full text of the license can be found in the
-LICENSE file included with this module.
-
-=cut
+package Parse::CPAN::Meta;
+
+use strict;
+use Carp 'croak';
+
+# UTF Support?
+sub HAVE_UTF8 () { $] >= 5.007003 }
+BEGIN {
+ if ( HAVE_UTF8 ) {
+ # The string eval helps hide this from Test::MinimumVersion
+ eval "require utf8;";
+ die "Failed to load UTF-8 support" if $@;
+ }
+
+ # Class structure
+ require 5.004;
+ require Exporter;
+ $Parse::CPAN::Meta::VERSION = '1.38';
+ @Parse::CPAN::Meta::ISA = qw{ Exporter };
+ @Parse::CPAN::Meta::EXPORT_OK = qw{ Load LoadFile };
+}
+
+# Prototypes
+sub LoadFile ($);
+sub Load ($);
+sub _scalar ($$$);
+sub _array ($$$);
+sub _hash ($$$);
+
+# Printable characters for escapes
+my %UNESCAPES = (
+ z => "\x00", a => "\x07", t => "\x09",
+ n => "\x0a", v => "\x0b", f => "\x0c",
+ r => "\x0d", e => "\x1b", '\\' => '\\',
+);
+
+
+
+
+
+#####################################################################
+# Implementation
+
+# Create an object from a file
+sub LoadFile ($) {
+ # Check the file
+ my $file = shift;
+ croak('You did not specify a file name') unless $file;
+ croak( "File '$file' does not exist" ) unless -e $file;
+ croak( "'$file' is a directory, not a file" ) unless -f _;
+ croak( "Insufficient permissions to read '$file'" ) unless -r _;
+
+ # Slurp in the file
+ local $/ = undef;
+ local *CFG;
+ unless ( open( CFG, $file ) ) {
+ croak("Failed to open file '$file': $!");
+ }
+ my $yaml = <CFG>;
+ unless ( close(CFG) ) {
+ croak("Failed to close file '$file': $!");
+ }
+
+ # Hand off to the actual parser
+ Load( $yaml );
+}
+
+# Parse a document from a string.
+# Doing checks on $_[0] prevents us having to do a string copy.
+sub Load ($) {
+ my $string = $_[0];
+ unless ( defined $string ) {
+ croak("Did not provide a string to load");
+ }
+
+ # Byte order marks
+ if ( $string =~ /^(?:\376\377|\377\376|\377\376\0\0|\0\0\376\377)/ ) {
+ croak("Stream has a non UTF-8 Unicode Byte Order Mark");
+ } else {
+ # Strip UTF-8 bom if found, we'll just ignore it
+ $string =~ s/^\357\273\277//;
+ }
+
+ # Try to decode as utf8
+ utf8::decode($string) if HAVE_UTF8;
+
+ # Check for some special cases
+ return () unless length $string;
+ unless ( $string =~ /[\012\015]+\z/ ) {
+ croak("Stream does not end with newline character");
+ }
+
+ # Split the file into lines
+ my @lines = grep { ! /^\s*(?:\#.*)?\z/ }
+ split /(?:\015{1,2}\012|\015|\012)/, $string;
+
+ # Strip the initial YAML header
+ @lines and $lines[0] =~ /^\%YAML[: ][\d\.]+.*\z/ and shift @lines;
+
+ # A nibbling parser
+ my @documents = ();
+ while ( @lines ) {
+ # Do we have a document header?
+ if ( $lines[0] =~ /^---\s*(?:(.+)\s*)?\z/ ) {
+ # Handle scalar documents
+ shift @lines;
+ if ( defined $1 and $1 !~ /^(?:\#.+|\%YAML[: ][\d\.]+)\z/ ) {
+ push @documents, _scalar( "$1", [ undef ], \@lines );
+ next;
+ }
+ }
+
+ if ( ! @lines or $lines[0] =~ /^(?:---|\.\.\.)/ ) {
+ # A naked document
+ push @documents, undef;
+ while ( @lines and $lines[0] !~ /^---/ ) {
+ shift @lines;
+ }
+
+ } elsif ( $lines[0] =~ /^\s*\-/ ) {
+ # An array at the root
+ my $document = [ ];
+ push @documents, $document;
+ _array( $document, [ 0 ], \@lines );
+
+ } elsif ( $lines[0] =~ /^(\s*)\S/ ) {
+ # A hash at the root
+ my $document = { };
+ push @documents, $document;
+ _hash( $document, [ length($1) ], \@lines );
+
+ } else {
+ croak("Parse::CPAN::Meta failed to classify line '$lines[0]'");
+ }
+ }
+
+ if ( wantarray ) {
+ return @documents;
+ } else {
+ return $documents[-1];
+ }
+}
+
+# Deparse a scalar string to the actual scalar
+sub _scalar ($$$) {
+ my ($string, $indent, $lines) = @_;
+
+ # Trim trailing whitespace
+ $string =~ s/\s*\z//;
+
+ # Explitic null/undef
+ return undef if $string eq '~';
+
+ # Quotes
+ if ( $string =~ /^\'(.*?)\'\z/ ) {
+ return '' unless defined $1;
+ $string = $1;
+ $string =~ s/\'\'/\'/g;
+ return $string;
+ }
+ if ( $string =~ /^\"((?:\\.|[^\"])*)\"\z/ ) {
+ # Reusing the variable is a little ugly,
+ # but avoids a new variable and a string copy.
+ $string = $1;
+ $string =~ s/\\"/"/g;
+ $string =~ s/\\([never\\fartz]|x([0-9a-fA-F]{2}))/(length($1)>1)?pack("H2",$2):$UNESCAPES{$1}/gex;
+ return $string;
+ }
+
+ # Special cases
+ if ( $string =~ /^[\'\"!&]/ ) {
+ croak("Parse::CPAN::Meta does not support a feature in line '$lines->[0]'");
+ }
+ return {} if $string eq '{}';
+ return [] if $string eq '[]';
+
+ # Regular unquoted string
+ return $string unless $string =~ /^[>|]/;
+
+ # Error
+ croak("Parse::CPAN::Meta failed to find multi-line scalar content") unless @$lines;
+
+ # Check the indent depth
+ $lines->[0] =~ /^(\s*)/;
+ $indent->[-1] = length("$1");
+ if ( defined $indent->[-2] and $indent->[-1] <= $indent->[-2] ) {
+ croak("Parse::CPAN::Meta found bad indenting in line '$lines->[0]'");
+ }
+
+ # Pull the lines
+ my @multiline = ();
+ while ( @$lines ) {
+ $lines->[0] =~ /^(\s*)/;
+ last unless length($1) >= $indent->[-1];
+ push @multiline, substr(shift(@$lines), length($1));
+ }
+
+ my $j = (substr($string, 0, 1) eq '>') ? ' ' : "\n";
+ my $t = (substr($string, 1, 1) eq '-') ? '' : "\n";
+ return join( $j, @multiline ) . $t;
+}
+
+# Parse an array
+sub _array ($$$) {
+ my ($array, $indent, $lines) = @_;
+
+ while ( @$lines ) {
+ # Check for a new document
+ if ( $lines->[0] =~ /^(?:---|\.\.\.)/ ) {
+ while ( @$lines and $lines->[0] !~ /^---/ ) {
+ shift @$lines;
+ }
+ return 1;
+ }
+
+ # Check the indent level
+ $lines->[0] =~ /^(\s*)/;
+ if ( length($1) < $indent->[-1] ) {
+ return 1;
+ } elsif ( length($1) > $indent->[-1] ) {
+ croak("Parse::CPAN::Meta found bad indenting in line '$lines->[0]'");
+ }
+
+ if ( $lines->[0] =~ /^(\s*\-\s+)[^\'\"]\S*\s*:(?:\s+|$)/ ) {
+ # Inline nested hash
+ my $indent2 = length("$1");
+ $lines->[0] =~ s/-/ /;
+ push @$array, { };
+ _hash( $array->[-1], [ @$indent, $indent2 ], $lines );
+
+ } elsif ( $lines->[0] =~ /^\s*\-(\s*)(.+?)\s*\z/ ) {
+ # Array entry with a value
+ shift @$lines;
+ push @$array, _scalar( "$2", [ @$indent, undef ], $lines );
+
+ } elsif ( $lines->[0] =~ /^\s*\-\s*\z/ ) {
+ shift @$lines;
+ unless ( @$lines ) {
+ push @$array, undef;
+ return 1;
+ }
+ if ( $lines->[0] =~ /^(\s*)\-/ ) {
+ my $indent2 = length("$1");
+ if ( $indent->[-1] == $indent2 ) {
+ # Null array entry
+ push @$array, undef;
+ } else {
+ # Naked indenter
+ push @$array, [ ];
+ _array( $array->[-1], [ @$indent, $indent2 ], $lines );
+ }
+
+ } elsif ( $lines->[0] =~ /^(\s*)\S/ ) {
+ push @$array, { };
+ _hash( $array->[-1], [ @$indent, length("$1") ], $lines );
+
+ } else {
+ croak("Parse::CPAN::Meta failed to classify line '$lines->[0]'");
+ }
+
+ } elsif ( defined $indent->[-2] and $indent->[-1] == $indent->[-2] ) {
+ # This is probably a structure like the following...
+ # ---
+ # foo:
+ # - list
+ # bar: value
+ #
+ # ... so lets return and let the hash parser handle it
+ return 1;
+
+ } else {
+ croak("Parse::CPAN::Meta failed to classify line '$lines->[0]'");
+ }
+ }
+
+ return 1;
+}
+
+# Parse an array
+sub _hash ($$$) {
+ my ($hash, $indent, $lines) = @_;
+
+ while ( @$lines ) {
+ # Check for a new document
+ if ( $lines->[0] =~ /^(?:---|\.\.\.)/ ) {
+ while ( @$lines and $lines->[0] !~ /^---/ ) {
+ shift @$lines;
+ }
+ return 1;
+ }
+
+ # Check the indent level
+ $lines->[0] =~ /^(\s*)/;
+ if ( length($1) < $indent->[-1] ) {
+ return 1;
+ } elsif ( length($1) > $indent->[-1] ) {
+ croak("Parse::CPAN::Meta found bad indenting in line '$lines->[0]'");
+ }
+
+ # Get the key
+ unless ( $lines->[0] =~ s/^\s*([^\'\" ][^\n]*?)\s*:(\s+|$)// ) {
+ if ( $lines->[0] =~ /^\s*[?\'\"]/ ) {
+ croak("Parse::CPAN::Meta does not support a feature in line '$lines->[0]'");
+ }
+ croak("Parse::CPAN::Meta failed to classify line '$lines->[0]'");
+ }
+ my $key = $1;
+
+ # Do we have a value?
+ if ( length $lines->[0] ) {
+ # Yes
+ $hash->{$key} = _scalar( shift(@$lines), [ @$indent, undef ], $lines );
+ } else {
+ # An indent
+ shift @$lines;
+ unless ( @$lines ) {
+ $hash->{$key} = undef;
+ return 1;
+ }
+ if ( $lines->[0] =~ /^(\s*)-/ ) {
+ $hash->{$key} = [];
+ _array( $hash->{$key}, [ @$indent, length($1) ], $lines );
+ } elsif ( $lines->[0] =~ /^(\s*)./ ) {
+ my $indent2 = length("$1");
+ if ( $indent->[-1] >= $indent2 ) {
+ # Null hash entry
+ $hash->{$key} = undef;
+ } else {
+ $hash->{$key} = {};
+ _hash( $hash->{$key}, [ @$indent, length($1) ], $lines );
+ }
+ }
+ }
+ }
+
+ return 1;
+}
+
+1;
+
+__END__
+
+=pod
+
+=head1 NAME
+
+Parse::CPAN::Meta - Parse META.yml and other similar CPAN metadata files
+
+=head1 SYNOPSIS
+
+ #############################################
+ # In your file
+
+ ---
+ rootproperty: blah
+ section:
+ one: two
+ three: four
+ Foo: Bar
+ empty: ~
+
+
+
+ #############################################
+ # In your program
+
+ use Parse::CPAN::Meta;
+
+ # Create a YAML file
+ my @yaml = Parse::CPAN::Meta::LoadFile( 'Meta.yml' );
+
+ # Reading properties
+ my $root = $yaml[0]->{rootproperty};
+ my $one = $yaml[0]->{section}->{one};
+ my $Foo = $yaml[0]->{section}->{Foo};
+
+=head1 DESCRIPTION
+
+B<Parse::CPAN::Meta> is a parser for F<META.yml> files, based on the
+parser half of L<YAML::Tiny>.
+
+It supports a basic subset of the full YAML specification, enough to
+implement parsing of typical F<META.yml> files, and other similarly simple
+YAML files.
+
+If you need something with more power, move up to a full YAML parser such
+as L<YAML>, L<YAML::Syck> or L<YAML::LibYAML>.
+
+B<Parse::CPAN::Meta> provides a very simply API of only two functions,
+based on the YAML functions of the same name. Wherever possible,
+identical calling semantics are used.
+
+All error reporting is done with exceptions (die'ing).
+
+=head1 FUNCTIONS
+
+For maintenance clarity, no functions are exported.
+
+=head2 Load
+
+ my @yaml = Load( $string );
+
+Parses a string containing a valid YAML stream into a list of Perl data
+structures.
+
+=head2 LoadFile
+
+ my @yaml = LoadFile( 'META.yml' );
+
+Reads the YAML stream from a file instead of a string.
+
+=head1 SUPPORT
+
+Bugs should be reported via the CPAN bug tracker at
+
+L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Parse-CPAN-Meta>
+
+=head1 AUTHOR
+
+Adam Kennedy E<lt>adamk@cpan.orgE<gt>
+
+=head1 SEE ALSO
+
+L<YAML>, L<YAML::Syck>, L<Config::Tiny>, L<CSS::Tiny>,
+L<http://use.perl.org/~Alias/journal/29427>, L<http://ali.as/>
+
+=head1 COPYRIGHT
+
+Copyright 2006 - 2009 Adam Kennedy.
+
+This program is free software; you can redistribute
+it and/or modify it under the same terms as Perl itself.
+
+The full text of the license can be found in the
+LICENSE file included with this module.
+
+=cut
diff --git a/lib/Parse/CPAN/Meta/Changes b/lib/Parse/CPAN/Meta/Changes
index d602d4a58c..21fc89605c 100644
--- a/lib/Parse/CPAN/Meta/Changes
+++ b/lib/Parse/CPAN/Meta/Changes
@@ -1,5 +1,13 @@
Revision history for Perl extension Parse-CPAN-Meta
+1.38 Sat 16 May 2009
+ - Synchorised version numbers with YAML::Tiny
+ - Code shrinkages to the bloaty Unicode/BOM code
+ - Merging a ton more tests from YAML::Tiny
+ - Added back some pointless options to yaml_ok that keep our
+ codebase closer to YAML::Tiny (which should help with syncing)
+ - Changed exceptions to be closer to YAML::Tiny
+
0.05 Wed 11 Mar 2009
- Upgrade previous release to a stable release.
diff --git a/lib/Parse/CPAN/Meta/t/02_basic.t b/lib/Parse/CPAN/Meta/t/02_basic.t
index 6b65e0261a..f6a91c1707 100644
--- a/lib/Parse/CPAN/Meta/t/02_basic.t
+++ b/lib/Parse/CPAN/Meta/t/02_basic.t
@@ -56,26 +56,31 @@ yaml_ok(
"---\n",
[ undef ],
'only_header',
+ noyamlperl => 1,
);
yaml_ok(
"---\n---\n",
[ undef, undef ],
'two_header',
+ noyamlperl => 1,
);
yaml_ok(
"--- ~\n",
[ undef ],
'one_undef',
+ noyamlperl => 1,
);
yaml_ok(
"--- ~\n",
[ undef ],
'one_undef2',
+ noyamlperl => 1,
);
yaml_ok(
"--- ~\n---\n",
[ undef, undef ],
'two_undef',
+ noyamlperl => 1,
);
# Just a scalar
@@ -110,6 +115,7 @@ yaml_ok(
"---\n- ~\n- bar\n",
[ [ undef, 'bar' ] ],
'one_listundef',
+ noyamlperl => 1,
);
# Simple hashs
@@ -123,6 +129,7 @@ yaml_ok(
"---\nfoo: bar\nthis: ~\n",
[ { this => undef, foo => 'bar' } ],
'one_hash2',
+ noyamlperl => 1,
);
# Simple array inside a hash with an undef
@@ -136,6 +143,7 @@ foo:
END_YAML
[ { foo => [ 'bar', undef, 'baz' ] } ],
'array_in_hash',
+ noyamlperl => 1,
);
# Simple hash inside a hash with an undef
@@ -148,6 +156,7 @@ bar:
END_YAML
[ { foo => undef, bar => { foo => 'bar' } } ],
'hash_in_hash',
+ noyamlperl => 1,
);
# Mixed hash and scalars inside an array
@@ -170,6 +179,7 @@ END_YAML
{ foo => 'bar', this => 'that' },
] ],
'hash_in_array',
+ noyamlperl => 1,
);
# Simple single quote
@@ -194,12 +204,16 @@ yaml_ok(
"--- \" \"\n",
[ ' ' ],
"only_spaces",
+ noyamlpm => 1,
+ noyamlperl => 1,
);
yaml_ok(
"--- \" foo\"\n--- \"bar \"\n",
[ " foo", "bar " ],
"leading_trailing_spaces",
+ noyamlpm => 1,
+ noyamlperl => 1,
);
# Implicit document start
@@ -225,6 +239,7 @@ yaml_ok(
END_YAML
[ [ undef, { foo => 'bar', this => 'that' }, 'baz' ] ],
'inline_nested_hash',
+ noyamlperl => 1,
);
# Empty comments
diff --git a/lib/Parse/CPAN/Meta/t/03_regression.t b/lib/Parse/CPAN/Meta/t/03_regression.t
index 1a1436a9d7..e9fb70a8fb 100644
--- a/lib/Parse/CPAN/Meta/t/03_regression.t
+++ b/lib/Parse/CPAN/Meta/t/03_regression.t
@@ -20,7 +20,7 @@ BEGIN {
use File::Spec::Functions ':ALL';
use Parse::CPAN::Meta::Test;
-use Test::More tests(20);
+use Test::More tests(37);
@@ -62,42 +62,91 @@ yaml_ok(
);
# Piped multi-line scalar
-yaml_ok( <<'END_YAML', [ [ "foo\nbar\n", 1 ] ], 'indented', nosyck => 1 );
+yaml_ok(
+ <<'END_YAML',
---
- |
foo
bar
- 1
END_YAML
+ [ [ "foo\nbar\n", 1 ] ],
+ 'indented',
+);
# ... with a pointless hyphen
-yaml_ok( <<'END_YAML', [ [ "foo\nbar", 1 ] ], 'indented', nosyck => 1 );
+yaml_ok( <<'END_YAML',
---
- |-
foo
bar
- 1
END_YAML
-
+ [ [ "foo\nbar", 1 ] ],
+ 'indented',
+);
#####################################################################
-# Support for YAML document version declarations
+# Support for YAML version directives
-# Simple case
+# Simple inline case (comment variant)
yaml_ok(
<<'END_YAML',
--- #YAML:1.0
foo: bar
END_YAML
[ { foo => 'bar' } ],
- 'simple_doctype',
+ 'simple_doctype_comment',
+ nosyck => 1,
+);
+
+# Simple inline case (percent variant)
+yaml_ok(
+ <<'END_YAML',
+--- %YAML:1.0
+foo: bar
+END_YAML
+ [ { foo => 'bar' } ],
+ 'simple_doctype_percent',
+ noyamlpm => 1,
+ noxs => 1,
+ noyamlperl => 1,
+);
+
+# Simple header (comment variant)
+yaml_ok(
+ <<'END_YAML',
+%YAML:1.0
+---
+foo: bar
+END_YAML
+ [ { foo => 'bar' } ],
+ 'predocument_1_0',
+ noyamlpm => 1,
+ nosyck => 1,
+ noxs => 1,
+ noyamlperl => 1,
);
-# Multiple documents
+# Simple inline case (comment variant)
+yaml_ok(
+ <<'END_YAML',
+%YAML 1.1
+---
+foo: bar
+END_YAML
+ [ { foo => 'bar' } ],
+ 'predocument_1_1',
+ noyamlpm => 1,
+ nosyck => 1,
+ noyamlperl => 1,
+);
+
+# Multiple inline documents (comment variant)
yaml_ok(
<<'END_YAML',
--- #YAML:1.0
@@ -108,7 +157,32 @@ foo: bar
foo: bar
END_YAML
[ { foo => 'bar' }, [ 1 ], { foo => 'bar' } ],
- 'multi_doctype',
+ 'multi_doctype_comment',
+);
+
+# Simple pre-document case (comment variant)
+yaml_ok(
+ <<'END_YAML',
+%YAML 1.1
+---
+foo: bar
+END_YAML
+ [ { foo => 'bar' } ],
+ 'predocument_percent',
+ noyamlpm => 1,
+ nosyck => 1,
+ noyamlperl => 1,
+);
+
+# Simple pre-document case (comment variant)
+yaml_ok(
+ <<'END_YAML',
+#YAML 1.1
+---
+foo: bar
+END_YAML
+ [ { foo => 'bar' } ],
+ 'predocument_comment',
);
@@ -192,8 +266,13 @@ arr:
- ~
- 'bar'
END_YAML
- [ { abstract => 'Generate fractal curves', foo => undef, arr => [ 'foo', undef, 'bar' ] } ],
+ [ {
+ abstract => 'Generate fractal curves',
+ foo => undef,
+ arr => [ 'foo', undef, 'bar' ],
+ } ],
'trailing whitespace',
+ noyamlperl => 1,
);
@@ -218,15 +297,35 @@ END_YAML
#####################################################################
-# Single Quote Idiosyncracy
+# Quote and Escaping Idiosyncracies
+
+yaml_ok(
+ <<'END_YAML',
+---
+name1: 'O''Reilly'
+name2: 'O''Reilly O''Tool'
+name3: 'Double '''' Quote'
+END_YAML
+ [ {
+ name1 => "O'Reilly",
+ name2 => "O'Reilly O'Tool",
+ name3 => "Double '' Quote",
+ } ],
+ 'single quote subtleties',
+);
yaml_ok(
<<'END_YAML',
---
-slash: '\\'
-name: 'O''Reilly'
+slash1: '\\'
+slash2: '\\foo'
+slash3: '\\foo\\\\'
END_YAML
- [ { slash => "\\\\", name => "O'Reilly" } ],
+ [ {
+ slash1 => "\\\\",
+ slash2 => "\\\\foo",
+ slash3 => "\\\\foo\\\\\\\\",
+ } ],
'single quote subtleties',
);
@@ -246,6 +345,8 @@ build_requires:
END_YAML
[ { foo => 0, requires => undef, build_requires => undef } ],
'empty hash keys',
+ noyamlpm => 1,
+ noyamlperl => 1,
);
yaml_ok(
@@ -257,6 +358,8 @@ yaml_ok(
END_YAML
[ [ 'foo', undef, undef ] ],
'empty array keys',
+ noyamlpm => 1,
+ noyamlperl => 1,
);
@@ -273,6 +376,8 @@ foo: bar
END_YAML
[ { foo => 'bar' } ],
'comment header',
+ noyamlpm => 1,
+ noyamlperl => 1,
);
@@ -295,6 +400,163 @@ END_YAML
+#####################################################################
+# Confirm we can read the synopsis
+
+yaml_ok(
+ <<'END_YAML',
+---
+rootproperty: blah
+section:
+ one: two
+ three: four
+ Foo: Bar
+ empty: ~
+END_YAML
+ [ {
+ rootproperty => 'blah',
+ section => {
+ one => 'two',
+ three => 'four',
+ Foo => 'Bar',
+ empty => undef,
+ },
+ } ],
+ 'synopsis',
+ noyamlperl => 1,
+);
+
+
+
+
+
+#####################################################################
+# Unprintable Characters
+
+yaml_ok(
+ "--- \"foo\\n\\x00\"\n",
+ [ "foo\n\0" ],
+ 'unprintable',
+);
+
+
+
+
+
+#####################################################################
+# Empty Quote Line
+
+yaml_ok(
+ <<'END_YAML',
+---
+- foo
+#
+- bar
+END_YAML
+ [ [ "foo", "bar" ] ],
+);
+
+
+
+
+
+#####################################################################
+# Indentation after empty hash value
+
+yaml_ok(
+ <<'END_YAML',
+---
+Test:
+ optmods:
+ Bad: 0
+ Foo: 1
+ Long: 0
+ version: 5
+Test_IncludeA:
+ optmods:
+Test_IncludeB:
+ optmods:
+_meta:
+ name: 'test profile'
+ note: 'note this test profile'
+END_YAML
+ [ {
+ Test => {
+ optmods => {
+ Bad => 0,
+ Foo => 1,
+ Long => 0,
+ },
+ version => 5,
+ },
+ Test_IncludeA => {
+ optmods => undef,
+ },
+ Test_IncludeB => {
+ optmods => undef,
+ },
+ _meta => {
+ name => 'test profile',
+ note => 'note this test profile',
+ },
+ } ],
+ 'Indentation after empty hash value',
+ noyamlperl => 1,
+);
+
+
+
+
+
+#####################################################################
+# Spaces in the Key
+
+yaml_ok(
+ <<'END_YAML',
+---
+the key: the value
+END_YAML
+ [ { 'the key' => 'the value' } ],
+);
+
+
+
+
+
+#####################################################################
+# Ticker #32402
+
+# Tests a particular pathological case
+
+yaml_ok(
+ <<'END_YAML',
+---
+- value
+- '><'
+END_YAML
+ [ [ 'value', '><' ] ],
+ 'Pathological >< case',
+);
+
+
+
+
+
+#####################################################################
+# Special Characters
+
+#yaml_ok(
+# <<'END_YAML',
+#---
+#- "Ingy d\xC3\xB6t Net"
+#END_YAML
+# [ [ "Ingy d\xC3\xB6t Net" ] ],
+#);
+
+
+
+
+
######################################################################
# Non-Indenting Sub-List
@@ -308,4 +570,53 @@ bar: value
END_YAML
[ { foo => [ 'list' ], bar => 'value' } ],
'Non-indenting sub-list',
+ noyamlpm => 1,
+ noyamlperl => 1,
+);
+
+
+
+
+
+
+#####################################################################
+# Check Multiple-Escaping
+
+# RT #42119: write of two single quotes
+yaml_ok(
+ "--- \"A'B'C\"\n",
+ [ "A'B'C" ],
+ 'Multiple escaping of quote ok',
+);
+
+# Escapes without whitespace
+yaml_ok(
+ "--- A\\B\\C\n",
+ [ "A\\B\\C" ],
+ 'Multiple escaping of escape ok',
+);
+
+# Escapes with whitespace
+yaml_ok(
+ "--- 'A\\B \\C'\n",
+ [ "A\\B \\C" ],
+ 'Multiple escaping of escape with whitespace ok',
+);
+
+
+
+
+
+######################################################################
+# Check illegal characters that are in legal places
+
+yaml_ok(
+ "--- 'Wow!'\n",
+ [ "Wow!" ],
+ 'Bang in a quote',
+);
+yaml_ok(
+ "--- 'This&that'\n",
+ [ "This&that" ],
+ 'Ampersand in a quote',
);
diff --git a/lib/Parse/CPAN/Meta/t/05_export.t b/lib/Parse/CPAN/Meta/t/05_export.t
new file mode 100644
index 0000000000..f82cc91cf6
--- /dev/null
+++ b/lib/Parse/CPAN/Meta/t/05_export.t
@@ -0,0 +1,29 @@
+#!/usr/bin/perl
+
+# Testing of basic document structures
+
+BEGIN {
+ if( $ENV{PERL_CORE} ) {
+ chdir 't';
+ @INC = ('../lib', 'lib');
+ }
+ else {
+ unshift @INC, 't/lib/';
+ }
+}
+
+use strict;
+BEGIN {
+ $| = 1;
+ $^W = 1;
+}
+
+use Test::More tests => 4;
+use Parse::CPAN::Meta;
+
+
+
+ok not(defined &main::Load), 'Load is not exported';
+ok not(defined &main::Dump), 'Dump is not exported';
+ok not(defined &main::LoadFile), 'LoadFile is not exported';
+ok not(defined &main::DumpFile), 'DumpFile is not exported';
diff --git a/lib/Parse/CPAN/Meta/t/11_meta_yml.t b/lib/Parse/CPAN/Meta/t/11_meta_yml.t
index c5a493467d..fe95d1abef 100644
--- a/lib/Parse/CPAN/Meta/t/11_meta_yml.t
+++ b/lib/Parse/CPAN/Meta/t/11_meta_yml.t
@@ -20,14 +20,14 @@ BEGIN {
use File::Spec::Functions ':ALL';
use Parse::CPAN::Meta::Test;
-use Test::More tests(8, 2);
+use Test::More tests(8, 3);
#####################################################################
-# Testing YAML::Tiny's META.yml file
+# Testing YAML::Tiny's own META.yml file
yaml_ok(
<<'END_YAML',
@@ -198,6 +198,7 @@ END_YAML
generated_by => 'ExtUtils::MakeMaker version 6.17',
} ],
'Acme-Time-Baby',
+ noyamlperl => 1,
);
@@ -209,30 +210,6 @@ END_YAML
yaml_ok(
<<'END_YAML',
---- %YAML:1.0
-name: Data-Swap
-version: 0.05
-license: perl
-distribution_type: module
-requires:
- perl: 5.6.0
-dynamic_config: 0
-END_YAML
- [ {
- name => 'Data-Swap',
- version => '0.05',
- license => 'perl',
- distribution_type => 'module',
- requires => {
- perl => '5.6.0',
- },
- dynamic_config => '0',
- } ],
- 'Data-Swap',
-);
-
-yaml_ok(
- <<'END_YAML',
--- #YAML:1.0
name: Data-Swap
version: 0.05
@@ -253,6 +230,7 @@ END_YAML
dynamic_config => '0',
} ],
'Data-Swap',
+ nosyck => 1,
);
@@ -293,6 +271,7 @@ SCOPE: {
version => '1.2.1',
} ],
'Template-Provider-Unicode-Japanese',
+ noyamlperl => 1,
);
}
@@ -314,5 +293,113 @@ SCOPE: {
version => '0.04',
} ],
'HTML-WebDAO',
+ nosyck => 1,
+ );
+}
+
+SCOPE: {
+ my $content = load_ok(
+ 'Spreadsheet-Read.yml',
+ catfile( test_data_directory(), 'Spreadsheet-Read.yml' ),
+ 100
+ );
+ yaml_ok(
+ $content,
+ [ {
+ 'resources' => {
+ 'license' => 'http://dev.perl.org/licenses/'
+ },
+ 'meta-spec' => {
+ 'version' => '1.4',
+ 'url' => 'http://module-build.sourceforge.net/META-spec-v1.4.html'
+ },
+ 'distribution_type' => 'module',
+ 'generated_by' => 'Author',
+ 'version' => 'VERSION',
+ 'name' => 'Read',
+ 'author' => [
+ 'H.Merijn Brand <h.m.brand@xs4all.nl>'
+ ],
+ 'license' => 'perl',
+ 'build_requires' => {
+ 'Test::More' => '0',
+ 'Test::Harness' => '0',
+ 'perl' => '5.006'
+ },
+ 'provides' => {
+ 'Spreadsheet::Read' => {
+ 'version' => 'VERSION',
+ 'file' => 'Read.pm'
+ }
+ },
+ 'optional_features' => [
+ {
+ 'opt_csv' => {
+ 'requires' => {
+ 'Text::CSV_XS' => '0.23'
+ },
+ 'recommends' => {
+ 'Text::CSV_PP' => '1.10',
+ 'Text::CSV_XS' => '0.58',
+ 'Text::CSV' => '1.10'
+ },
+ 'description' => 'Provides parsing of CSV streams'
+ }
+ },
+ {
+ 'opt_excel' => {
+ 'requires' => {
+ 'Spreadsheet::ParseExcel' => '0.26',
+ 'Spreadsheet::ParseExcel::FmtDefault' => '0'
+ },
+ 'recommends' => {
+ 'Spreadsheet::ParseExcel' => '0.42'
+ },
+ 'description' => 'Provides parsing of Microsoft Excel files'
+ }
+ },
+ {
+ 'opt_excelx' => {
+ 'requires' => {
+ 'Spreadsheet::XLSX' => '0.07'
+ },
+ 'description' => 'Provides parsing of Microsoft Excel 2007 files'
+ }
+ },
+ {
+ 'opt_oo' => {
+ 'requires' => {
+ 'Spreadsheet::ReadSXC' => '0.2'
+ },
+ 'description' => 'Provides parsing of OpenOffice spreadsheets'
+ }
+ },
+ {
+ 'opt_tools' => {
+ 'recommends' => {
+ 'Tk::TableMatrix::Spreadsheet' => '0',
+ 'Tk::NoteBook' => '0',
+ 'Tk' => '0'
+ },
+ 'description' => 'Spreadsheet tools'
+ }
+ }
+ ],
+ 'requires' => {
+ 'perl' => '5.006',
+ 'Data::Dumper' => '0',
+ 'Exporter' => '0',
+ 'Carp' => '0'
+ },
+ 'recommends' => {
+ 'perl' => '5.008005',
+ 'IO::Scalar' => '0',
+ 'File::Temp' => '0.14'
+ },
+ 'abstract' => 'Meta-Wrapper for reading spreadsheet data'
+ } ],
+ 'Spreadsheet-Read',
+ noyamlpm => 1,
+ noyamlperl => 1,
);
}
diff --git a/lib/Parse/CPAN/Meta/t/12_plagger.t b/lib/Parse/CPAN/Meta/t/12_plagger.t
index 68f3761417..5e186f3bc6 100644
--- a/lib/Parse/CPAN/Meta/t/12_plagger.t
+++ b/lib/Parse/CPAN/Meta/t/12_plagger.t
@@ -101,8 +101,8 @@ plugins:
nickname: plaggerbot
server_host: chat.freenode.net
server_channels:
- - #plagger-ja
- - #plagger
+ - '#plagger-ja'
+ - '#plagger'
END_YAML
diff --git a/lib/Parse/CPAN/Meta/t/13_perl_smith.t b/lib/Parse/CPAN/Meta/t/13_perl_smith.t
index 557f9bbf9b..9a8b8be709 100644
--- a/lib/Parse/CPAN/Meta/t/13_perl_smith.t
+++ b/lib/Parse/CPAN/Meta/t/13_perl_smith.t
@@ -153,4 +153,6 @@ yaml_ok(
},
} ],
'vanilla.yml',
+ nosyck => 1,
+ noyamlperl => 1,
);
diff --git a/lib/Parse/CPAN/Meta/t/14_yaml_org.t b/lib/Parse/CPAN/Meta/t/14_yaml_org.t
index 5f01274457..254bd7a547 100644
--- a/lib/Parse/CPAN/Meta/t/14_yaml_org.t
+++ b/lib/Parse/CPAN/Meta/t/14_yaml_org.t
@@ -68,5 +68,5 @@ Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.
END_TEXT
} ],
'sample.yml',
-
+ # nosyck => 1,
);
diff --git a/lib/Parse/CPAN/Meta/t/15_multibyte.t b/lib/Parse/CPAN/Meta/t/15_multibyte.t
index a67c0f989a..214b8b0c26 100644
--- a/lib/Parse/CPAN/Meta/t/15_multibyte.t
+++ b/lib/Parse/CPAN/Meta/t/15_multibyte.t
@@ -51,6 +51,3 @@ SKIP: {
skip "no utf8 support", 1 unless Parse::CPAN::Meta::HAVE_UTF8();
ok( utf8::is_utf8($yaml[0]->{author}), "utf8 decoded" );
}
-
-exit(0);
-
diff --git a/lib/Parse/CPAN/Meta/t/17_toolbar.t b/lib/Parse/CPAN/Meta/t/17_toolbar.t
index 2b2e06ec83..e0d3cf9876 100644
--- a/lib/Parse/CPAN/Meta/t/17_toolbar.t
+++ b/lib/Parse/CPAN/Meta/t/17_toolbar.t
@@ -55,4 +55,5 @@ yaml_ok(
]
} ],
'toolbar.yml',
+ noyamlperl => 1,
);
diff --git a/lib/Parse/CPAN/Meta/t/18_tap.t b/lib/Parse/CPAN/Meta/t/18_tap.t
new file mode 100644
index 0000000000..62b84f936e
--- /dev/null
+++ b/lib/Parse/CPAN/Meta/t/18_tap.t
@@ -0,0 +1,90 @@
+#!/usr/bin/perl
+
+# Testing relating to functionality in the Test Anything Protocol
+
+BEGIN {
+ if( $ENV{PERL_CORE} ) {
+ chdir 't';
+ @INC = ('../lib', 'lib');
+ }
+ else {
+ unshift @INC, 't/lib/';
+ }
+}
+
+use strict;
+BEGIN {
+ $| = 1;
+ $^W = 1;
+}
+
+use File::Spec::Functions ':ALL';
+use Parse::CPAN::Meta::Test;
+use Test::More tests(5, 0, 0);
+use Parse::CPAN::Meta ();
+
+
+
+
+
+#####################################################################
+# TAP Tests
+
+# Make sure we support x-foo keys
+yaml_ok(
+ "---\nx-foo: 1\n",
+ [ { 'x-foo' => 1 } ],
+ 'x-foo key',
+);
+
+# Document ending (hash)
+yaml_ok(
+ "---\n"
+ . " foo: bar\n"
+ . "...\n",
+ [ { foo => "bar" } ],
+ 'document_end_hash',
+ noyamlpm => 1,
+ nosyck => 1,
+ noyamlperl => 1,
+);
+
+# Document ending (array)
+yaml_ok(
+ "---\n"
+ . "- foo\n"
+ . "...\n",
+ [ [ 'foo' ] ],
+ 'document_end_array',
+ noyamlpm => 1,
+ noyamlperl => 1,
+);
+
+# Multiple documents (simple)
+yaml_ok(
+ "---\n"
+ . "- foo\n"
+ . "...\n"
+ . "---\n"
+ . "- foo\n"
+ . "...\n",
+ [ [ 'foo' ], [ 'foo' ] ],
+ 'multi_document_simple',
+ noyamlpm => 1,
+ noyamlperl => 1,
+);
+
+# Multiple documents (whitespace-separated)
+yaml_ok(
+ "---\n"
+ . "- foo\n"
+ . "...\n"
+ . "\n"
+ . "---\n"
+ . "- foo\n"
+ . "...\n",
+ [ [ 'foo' ], [ 'foo' ] ],
+ 'multi_document_space',
+ noyamlpm => 1,
+ noyamlperl => 1,
+);
diff --git a/lib/Parse/CPAN/Meta/t/19_errors.t b/lib/Parse/CPAN/Meta/t/19_errors.t
new file mode 100644
index 0000000000..baa06ad5b2
--- /dev/null
+++ b/lib/Parse/CPAN/Meta/t/19_errors.t
@@ -0,0 +1,43 @@
+#!/usr/bin/perl
+
+# Testing documents that should fail
+
+BEGIN {
+ if( $ENV{PERL_CORE} ) {
+ chdir 't';
+ @INC = ('../lib', 'lib');
+ }
+ else {
+ unshift @INC, 't/lib/';
+ }
+}
+
+use strict;
+BEGIN {
+ $| = 1;
+ $^W = 1;
+}
+
+use File::Spec::Functions ':ALL';
+use Parse::CPAN::Meta::Test;
+use Test::More tests => 1;
+
+
+
+
+
+#####################################################################
+# Missing Features
+
+# We don't support raw nodes
+yaml_error( <<'END_YAML', 'does not support a feature' );
+---
+version: !!perl/hash:version
+ original: v2.0.2
+ qv: 1
+ version:
+ - 2
+ - 0
+ - 2
+END_YAML
+
diff --git a/lib/Parse/CPAN/Meta/t/21_bom.t b/lib/Parse/CPAN/Meta/t/21_bom.t
new file mode 100644
index 0000000000..706cf77c3f
--- /dev/null
+++ b/lib/Parse/CPAN/Meta/t/21_bom.t
@@ -0,0 +1,39 @@
+#!/usr/bin/perl
+
+BEGIN {
+ if( $ENV{PERL_CORE} ) {
+ chdir 't';
+ @INC = ('../lib', 'lib');
+ }
+ else {
+ unshift @INC, 't/lib/';
+ }
+}
+
+use strict;
+BEGIN {
+ $| = 1;
+ $^W = 1;
+}
+
+use File::Spec::Functions ':ALL';
+use Parse::CPAN::Meta::Test;
+use Test::More tests(0, 1, 3);
+
+
+
+
+
+#####################################################################
+# Testing that Perl::Smith config files work
+
+my $sample_file = catfile( test_data_directory(), 'utf_16_le_bom.yml' );
+my $sample = load_ok( 'utf_16_le_bom.yml', $sample_file, 3 );
+
+# Does the string parse to the structure
+my $name = "utf-16";
+my $yaml_copy = $sample;
+my $yaml = eval { Parse::CPAN::Meta::Load( $yaml_copy ); };
+is( $yaml_copy, $sample, "$name: Parse::CPAN::Meta::Load does not modify the input string" );
+is( $yaml, undef, "file not parsed" );
+ok( $@ =~ "Stream has a non UTF-8 Unicode Byte Order Mark", "correct error" );
diff --git a/lib/Parse/CPAN/Meta/t/data/Spreadsheet-Read.yml b/lib/Parse/CPAN/Meta/t/data/Spreadsheet-Read.yml
new file mode 100644
index 0000000000..f402ab8d68
--- /dev/null
+++ b/lib/Parse/CPAN/Meta/t/data/Spreadsheet-Read.yml
@@ -0,0 +1,61 @@
+--- #YAML:1.1
+name: Read
+version: VERSION
+abstract: Meta-Wrapper for reading spreadsheet data
+license: perl
+author:
+ - H.Merijn Brand <h.m.brand@xs4all.nl>
+generated_by: Author
+distribution_type: module
+provides:
+ Spreadsheet::Read:
+ file: Read.pm
+ version: VERSION
+requires:
+ perl: 5.006
+ Exporter: 0
+ Carp: 0
+ Data::Dumper: 0
+recommends:
+ perl: 5.008005
+ File::Temp: 0.14
+ IO::Scalar: 0
+build_requires:
+ perl: 5.006
+ Test::Harness: 0
+ Test::More: 0
+optional_features:
+- opt_csv:
+ description: Provides parsing of CSV streams
+ requires:
+ Text::CSV_XS: 0.23
+ recommends:
+ Text::CSV: 1.10
+ Text::CSV_PP: 1.10
+ Text::CSV_XS: 0.58
+- opt_excel:
+ description: Provides parsing of Microsoft Excel files
+ requires:
+ Spreadsheet::ParseExcel: 0.26
+ Spreadsheet::ParseExcel::FmtDefault: 0
+ recommends:
+ Spreadsheet::ParseExcel: 0.42
+- opt_excelx:
+ description: Provides parsing of Microsoft Excel 2007 files
+ requires:
+ Spreadsheet::XLSX: 0.07
+- opt_oo:
+ description: Provides parsing of OpenOffice spreadsheets
+ requires:
+ Spreadsheet::ReadSXC: 0.2
+- opt_tools:
+ description: Spreadsheet tools
+ recommends:
+ Tk: 0
+ Tk::NoteBook: 0
+ Tk::TableMatrix::Spreadsheet: 0
+resources:
+ license: http://dev.perl.org/licenses/
+meta-spec:
+ version: 1.4
+ url: http://module-build.sourceforge.net/META-spec-v1.4.html