From: Steffen Mueller Date: Sun, 17 May 2009 09:55:50 +0000 (+0200) Subject: Upgrade to Parse::CPAN::Meta 1.38 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=de044c3605bd12a0b679b024ec9c16b44093c54b;p=p5sagit%2Fp5-mst-13.2.git Upgrade to Parse::CPAN::Meta 1.38 --- diff --git a/lib/Parse/CPAN/Meta.pm b/lib/Parse/CPAN/Meta.pm index afbb587..d65d7bb 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 = ; - 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 is a parser for META.yml files, based on the -parser half of L. - -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, L or L. - -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 - -=head1 AUTHOR - -Adam Kennedy Eadamk@cpan.orgE - -=head1 SEE ALSO - -L, L, L - -=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 = ; + 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 is a parser for F files, based on the +parser half of L. + +It supports a basic subset of the full YAML specification, enough to +implement parsing of typical F files, and other similarly simple +YAML files. + +If you need something with more power, move up to a full YAML parser such +as L, L or L. + +B 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 + +=head1 AUTHOR + +Adam Kennedy Eadamk@cpan.orgE + +=head1 SEE ALSO + +L, L, L, L, +L, L + +=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 d602d4a..21fc896 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 6b65e02..f6a91c1 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 1a1436a..e9fb70a 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 0000000..f82cc91 --- /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 c5a4934..fe95d1a 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 ' + ], + '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 68f3761..5e186f3 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 557f9bb..9a8b8be 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 5f01274..254bd7a 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 a67c0f9..214b8b0 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 2b2e06e..e0d3cf9 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 0000000..62b84f9 --- /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 0000000..baa06ad --- /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 0000000..706cf77 --- /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 0000000..f402ab8 --- /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 +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 diff --git a/t/lib/Parse/CPAN/Meta/Test.pm b/t/lib/Parse/CPAN/Meta/Test.pm index 319317a..46f967b 100644 --- a/t/lib/Parse/CPAN/Meta/Test.pm +++ b/t/lib/Parse/CPAN/Meta/Test.pm @@ -9,7 +9,10 @@ use vars qw{@ISA @EXPORT}; BEGIN { require Exporter; @ISA = qw{ Exporter }; - @EXPORT = qw{ tests yaml_ok slurp load_ok test_data_directory }; + @EXPORT = qw{ + tests yaml_ok yaml_error slurp load_ok + test_data_directory + }; } sub test_data_directory { @@ -53,6 +56,12 @@ sub yaml_ok { return 1; } +sub yaml_error { + my $string = shift; + my $yaml = eval { Parse::CPAN::Meta::Load( $string ); }; + Test::More::like( $@, qr/$_[0]/, "YAML::Tiny throws expected error" ); +} + sub slurp { my $file = shift; local $/ = undef;