Hello community, here is the log from the commit of package perl-Text-CSV for openSUSE:Factory checked in at 2019-01-05 14:41:22 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/perl-Text-CSV (Old) and /work/SRC/openSUSE:Factory/.perl-Text-CSV.new.28833 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-Text-CSV" Sat Jan 5 14:41:22 2019 rev:23 rq:662642 version:1.99 Changes: -------- --- /work/SRC/openSUSE:Factory/perl-Text-CSV/perl-Text-CSV.changes 2018-09-11 17:12:26.987858897 +0200 +++ /work/SRC/openSUSE:Factory/.perl-Text-CSV.new.28833/perl-Text-CSV.changes 2019-01-05 14:41:23.756529255 +0100 @@ -1,0 +2,20 @@ +Thu Jan 3 06:32:02 UTC 2019 - Stephan Kulow <[email protected]> + +- updated to 1.99 + see /usr/share/doc/packages/perl-Text-CSV/Changes + + 1.99 2019-01-02 + - Fixed a number of tests to skip for older perls + +------------------------------------------------------------------- +Wed Jan 2 06:35:27 UTC 2019 - Stephan Kulow <[email protected]> + +- updated to 1.98 + see /usr/share/doc/packages/perl-Text-CSV/Changes + + 1.98 2019-01-02 + - Imported tests/fixes from Text::CSV_XS 1.38 + - Added munge as alias for munge_column_names + - Added support for key-value pair and combined keys + +------------------------------------------------------------------- Old: ---- Text-CSV-1.97.tar.gz New: ---- Text-CSV-1.99.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-Text-CSV.spec ++++++ --- /var/tmp/diff_new_pack.a1Lphg/_old 2019-01-05 14:41:24.304528790 +0100 +++ /var/tmp/diff_new_pack.a1Lphg/_new 2019-01-05 14:41:24.308528786 +0100 @@ -1,7 +1,7 @@ # # spec file for package perl-Text-CSV # -# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -12,18 +12,18 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # Name: perl-Text-CSV -Version: 1.97 +Version: 1.99 Release: 0 %define cpan_name Text-CSV Summary: Comma-Separated Values Manipulator (Using Xs or Pureperl) License: Artistic-1.0 OR GPL-1.0-or-later Group: Development/Libraries/Perl -Url: http://search.cpan.org/dist/Text-CSV/ +Url: https://metacpan.org/release/%{cpan_name} Source0: https://cpan.metacpan.org/authors/id/I/IS/ISHIGAKI/%{cpan_name}-%{version}.tar.gz Source1: cpanspec.yml BuildArch: noarch @@ -46,11 +46,11 @@ %setup -q -n %{cpan_name}-%{version} %build -%{__perl} Makefile.PL INSTALLDIRS=vendor -%{__make} %{?_smp_mflags} +perl Makefile.PL INSTALLDIRS=vendor +make %{?_smp_mflags} %check -%{__make} test +make test %install %perl_make_install ++++++ Text-CSV-1.97.tar.gz -> Text-CSV-1.99.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV-1.97/Changes new/Text-CSV-1.99/Changes --- old/Text-CSV-1.97/Changes 2018-08-17 17:22:42.000000000 +0200 +++ new/Text-CSV-1.99/Changes 2019-01-02 12:48:53.000000000 +0100 @@ -1,5 +1,13 @@ Revision history for Perl extension Text::CSV. +1.99 2019-01-02 + - Fixed a number of tests to skip for older perls + +1.98 2019-01-02 + - Imported tests/fixes from Text::CSV_XS 1.38 + - Added munge as alias for munge_column_names + - Added support for key-value pair and combined keys + 1.97 2018-08-17 - Fix/add minimum perl version (GH-38, Kivanc Yazan++) - Updated MANIFEST diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV-1.97/META.json new/Text-CSV-1.99/META.json --- old/Text-CSV-1.97/META.json 2018-08-17 17:23:46.000000000 +0200 +++ new/Text-CSV-1.99/META.json 2019-01-02 12:50:22.000000000 +0100 @@ -54,6 +54,6 @@ "url" : "https://github.com/makamaka/Text-CSV" } }, - "version" : "1.97", + "version" : "1.99", "x_serialization_backend" : "JSON::PP version 2.94" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV-1.97/META.yml new/Text-CSV-1.99/META.yml --- old/Text-CSV-1.97/META.yml 2018-08-17 17:23:46.000000000 +0200 +++ new/Text-CSV-1.99/META.yml 2019-01-02 12:50:22.000000000 +0100 @@ -28,5 +28,5 @@ bugtracker: https://github.com/makamaka/Text-CSV/issues/ license: http://dev.perl.org/licenses/ repository: https://github.com/makamaka/Text-CSV -version: '1.97' +version: '1.99' x_serialization_backend: 'CPAN::Meta::YAML version 0.012' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV-1.97/lib/Text/CSV.pm new/Text-CSV-1.99/lib/Text/CSV.pm --- old/Text-CSV-1.97/lib/Text/CSV.pm 2018-08-17 17:20:20.000000000 +0200 +++ new/Text-CSV-1.99/lib/Text/CSV.pm 2019-01-02 12:49:00.000000000 +0100 @@ -9,7 +9,7 @@ @EXPORT_OK = qw( csv ); BEGIN { - $VERSION = '1.97'; + $VERSION = '1.99'; $DEBUG = 0; } @@ -141,52 +141,40 @@ =head1 SYNOPSIS +This section is taken from Text::CSV_XS. + + # Functional interface + use Text::CSV qw( csv ); + + # Read whole file in memory + my $aoa = csv (in => "data.csv"); # as array of array + my $aoh = csv (in => "data.csv", + headers => "auto"); # as array of hash + + # Write array of arrays as csv file + csv (in => $aoa, out => "file.csv", sep_char=> ";"); + + # Only show lines where "code" is odd + csv (in => "data.csv", filter => { code => sub { $_ % 2 }}); + + # Object interface use Text::CSV; my @rows; - my $csv = Text::CSV->new ( { binary => 1 } ) # should set binary attribute. - or die "Cannot use CSV: ".Text::CSV->error_diag (); - + # Read/parse CSV + my $csv = Text::CSV->new ({ binary => 1, auto_diag => 1 }); open my $fh, "<:encoding(utf8)", "test.csv" or die "test.csv: $!"; - while ( my $row = $csv->getline( $fh ) ) { + while (my $row = $csv->getline ($fh)) { $row->[2] =~ m/pattern/ or next; # 3rd field should match push @rows, $row; - } - $csv->eof or $csv->error_diag(); + } close $fh; - $csv->eol ("\r\n"); - + # and write as CSV open $fh, ">:encoding(utf8)", "new.csv" or die "new.csv: $!"; - $csv->print ($fh, $_) for @rows; + $csv->say ($fh, $_) for @rows; close $fh or die "new.csv: $!"; - # - # parse and combine style - # - - $status = $csv->combine(@columns); # combine columns into a string - $line = $csv->string(); # get the combined string - - $status = $csv->parse($line); # parse a CSV string into fields - @columns = $csv->fields(); # get the parsed fields - - $status = $csv->status (); # get the most recent status - $bad_argument = $csv->error_input (); # get the most recent bad argument - $diag = $csv->error_diag (); # if an error occurred, explains WHY - - $status = $csv->print ($io, $colref); # Write an array of fields - # immediately to a file $io - $colref = $csv->getline ($io); # Read a line from file $io, - # parse it and return an array - # ref of fields - $csv->column_names (@names); # Set column names for getline_hr () - $ref = $csv->getline_hr ($io); # getline (), but returns a hashref - $eof = $csv->eof (); # Indicate if last parse or - # getline () hit End Of File - - $csv->types(\@t_array); # Set column types - =head1 DESCRIPTION Text::CSV is a thin wrapper for L<Text::CSV_XS>-compatible modules now. @@ -222,7 +210,7 @@ =head1 NOTES -This section is taken from Text::CSV_XS. +This section is also taken from Text::CSV_XS. =head2 Embedded newlines @@ -837,6 +825,8 @@ This attribute is useful when exporting CSV data to be imported in custom loaders, like for MySQL, that recognize special sequences for C<NULL> data. +This attribute has no meaning when parsing CSV data. + =head3 verbatim my $csv = Text::CSV->new ({ verbatim => 1 }); @@ -913,6 +903,8 @@ escape_null => 1, quote_binary => 1, keep_meta_info => 0, + strict => 0, + formula => 0, verbatim => 0, undef_str => undef, types => undef, @@ -1917,9 +1909,12 @@ =head3 key If passed, will default L<C<headers>|/headers> to C<"auto"> and return a -hashref instead of an array of hashes. +hashref instead of an array of hashes. Allowed values are simple scalars or +array-references where the first element is the joiner and the rest are the +fields to join to combine the key. my $ref = csv (in => "test.csv", key => "code"); + my $ref = csv (in => "test.csv", key => [ ":" => "code", "color" ]); with test.csv like @@ -1928,7 +1923,7 @@ 2,keyboard,12,white 3,mouse,5,black -will return +the first example will return { 1 => { code => 1, @@ -1950,6 +1945,28 @@ } } +the second example will return + + { "1:gray" => { + code => 1, + color => 'gray', + price => 850, + product => 'pc' + }, + "2:white" => { + code => 2, + color => 'white', + price => 12, + product => 'keyboard' + }, + "3:black" => { + code => 3, + color => 'black', + price => 5, + product => 'mouse' + } + } + The C<key> attribute can be combined with L<C<headers>|/headers> for C<CSV> date that has no header line, like @@ -1959,6 +1976,76 @@ key => "c_foo", ); +=head3 value + +Used to create key-value hashes. + +Only allowed when C<key> is valid. A C<value> can be either a single column +label or an anonymous list of column labels. In the first case, the value +will be a simple scalar value, in the latter case, it will be a hashref. + + my $ref = csv (in => "test.csv", key => "code", + value => "price"); + my $ref = csv (in => "test.csv", key => "code", + value => [ "product", "price" ]); + my $ref = csv (in => "test.csv", key => [ ":" => "code", "color" ], + value => "price"); + my $ref = csv (in => "test.csv", key => [ ":" => "code", "color" ], + value => [ "product", "price" ]); + +with test.csv like + + code,product,price,color + 1,pc,850,gray + 2,keyboard,12,white + 3,mouse,5,black + +the first example will return + + { 1 => 850, + 2 => 12, + 3 => 5, + } + +the second example will return + + { 1 => { + price => 850, + product => 'pc' + }, + 2 => { + price => 12, + product => 'keyboard' + }, + 3 => { + price => 5, + product => 'mouse' + } + } + +the third example will return + + { "1:gray" => 850, + "2:white" => 12, + "3:black" => 5, + } + +the fourth example will return + + { "1:gray" => { + price => 850, + product => 'pc' + }, + "2:white" => { + price => 12, + product => 'keyboard' + }, + "3:black" => { + price => 5, + product => 'mouse' + } + } + =head3 keep_headers When using hashes, keep the column names into the arrayref passed, so all @@ -2516,6 +2603,16 @@ The C<key> attribute is of an unsupported type. =item * +1502 "PRM - The value attribute is passed without the key attribute" + +The C<value> attribute is only allowed when a valid key is given. + +=item * +1503 "PRM - The value attribute is passed as an unsupported type" + +The C<value> attribute is of an unsupported type. + +=item * 2010 "ECR - QUO char inside quotes followed by CR not part of EOL" When L<C<eol>|/eol> has been set to anything but the default, like diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV-1.97/lib/Text/CSV_PP.pm new/Text-CSV-1.99/lib/Text/CSV_PP.pm --- old/Text-CSV-1.97/lib/Text/CSV_PP.pm 2018-08-17 17:20:20.000000000 +0200 +++ new/Text-CSV-1.99/lib/Text/CSV_PP.pm 2019-01-02 12:49:00.000000000 +0100 @@ -12,7 +12,7 @@ use vars qw($VERSION @ISA @EXPORT_OK); use Carp; -$VERSION = '1.97'; +$VERSION = '1.99'; @ISA = qw(Exporter); @EXPORT_OK = qw(csv); @@ -52,6 +52,8 @@ # Syntax errors 1500 => "PRM - Invalid/unsupported arguments(s)", 1501 => "PRM - The key attribute is passed as an unsupported type", + 1502 => "PRM - The value attribute is passed without the key attribute", + 1503 => "PRM - The value attribute is passed as an unsupported type", # Parse errors 2010 => "ECR - QUO char inside quotes followed by CR not part of EOL", @@ -95,10 +97,7 @@ 3009 => "EHR - print_hr () called before column_names ()", 3010 => "EHR - print_hr () called with invalid arguments", - # PP Only Error - 4002 => "EIQ - Unescaped ESC in quoted field", - 4003 => "EIF - ESC CR", - 4004 => "EUF - Field is terminated by the escape character (escape_char)", + 4001 => "PRM - The key does not exist as field in the data", 0 => "", }; @@ -567,6 +566,15 @@ $self->{strict}; } +sub _SetDiagInfo { + my ($self, $err, $msg) = @_; + $self->SetDiag ($err); + my $em = $self->error_diag; + $em =~ s/^\d+$// and $msg =~ s/^/# /; + my $sep = $em =~ m/[;\n]$/ ? "\n\t" : ": "; + join $sep => grep m/\S\S\S/ => $em, $msg; + } + sub _supported_formula { my ($self, $f) = @_; defined $f or return 5; @@ -576,10 +584,9 @@ $f =~ m/^(?: 3 | diag )$/xi ? 3 : $f =~ m/^(?: 4 | empty | )$/xi ? 4 : $f =~ m/^(?: 5 | undef )$/xi ? 5 : do { - $self ||= "Text::CSV_PP"; - $self->SetDiag (1500); - croak "formula-handling '$f' is not supported\n"; - }; + $self ||= "Text::CSV_PP"; + croak ($self->_SetDiagInfo (1500, "formula-handling '$f' is not supported")); + }; } sub formula { @@ -940,6 +947,8 @@ croak (q{usage: $csv->header ($fh, [ seps ], { options })}); } + defined $args{munge} && !defined $args{munge_column_names} and + $args{munge_column_names} = $args{munge}; # munge as alias defined $args{detect_bom} or $args{detect_bom} = 1; defined $args{set_column_names} or $args{set_column_names} = 1; defined $args{munge_column_names} or $args{munge_column_names} = "lc"; @@ -953,7 +962,7 @@ if (defined $args{sep_set}) { ref $args{sep_set} eq "ARRAY" or - croak ($self->SetDiag (1500, "sep_set should be an array ref")); + croak ($self->_SetDiagInfo (1500, "sep_set should be an array ref")); @seps = @{$args{sep_set}}; } @@ -1030,9 +1039,12 @@ @hdr = map { $args{munge_column_names}->($_) } @hdr; ref $args{munge_column_names} eq "HASH" and @hdr = map { $args{munge_column_names}->{$_} || $_ } @hdr; - my %hdr = map { $_ => 1 } @hdr; - exists $hdr{""} and croak ($self->SetDiag (1012)); - keys %hdr == @hdr or croak ($self->SetDiag (1013)); + my %hdr; $hdr{$_}++ for @hdr; + exists $hdr{""} and croak ($self->SetDiag (1012)); + unless (keys %hdr == @hdr) { + croak ($self->_SetDiagInfo (1013, join ", " => + map { "$_ ($hdr{$_})" } grep { $hdr{$_} > 1 } keys %hdr)); + } $args{set_column_names} and $self->column_names (@hdr); wantarray ? @hdr : $self; } @@ -1271,6 +1283,7 @@ my $hdrs = delete $attr{headers}; my $frag = delete $attr{fragment}; my $key = delete $attr{key}; + my $val = delete $attr{value}; my $kh = delete $attr{keep_headers} || delete $attr{keep_column_names} || delete $attr{kh}; @@ -1330,6 +1343,7 @@ enc => $enc, hdrs => $hdrs, key => $key, + val => $val, kh => $kh, frag => $frag, fltr => $fltr, @@ -1413,15 +1427,20 @@ } if ($c->{kh}) { - ref $c->{kh} eq "ARRAY" or croak ($csv->SetDiag (1501, "1501 - PRM")); + ref $c->{kh} eq "ARRAY" or croak ($csv->SetDiag (1501)); $hdrs ||= "auto"; } my $key = $c->{key}; if ($key) { - ref $key and croak ($csv->SetDiag (1501, "1501 - PRM")); + !ref $key or ref $key eq "ARRAY" && @$key > 1 or croak ($csv->SetDiag (1501)); $hdrs ||= "auto"; } + my $val = $c->{val}; + if ($val) { + $key or croak ($csv->SetDiag (1502)); + !ref $val or ref $val eq "ARRAY" && @$val > 0 or croak ($csv->SetDiag (1503)); + } $c->{fltr} && grep m/\D/ => keys %{$c->{fltr}} and $hdrs ||= "auto"; if (defined $hdrs) { @@ -1476,9 +1495,30 @@ my $ref = ref $hdrs ? # aoh do { - $csv->column_names ($hdrs); + my @h = $csv->column_names ($hdrs); + my %h; $h{$_}++ for @h; + exists $h{""} and croak ($csv->SetDiag (1012)); + unless (keys %h == @h) { + croak ($csv->_SetDiagInfo (1013, join ", " => + map { "$_ ($h{$_})" } grep { $h{$_} > 1 } keys %h)); + } $frag ? $csv->fragment ($fh, $frag) : - $key ? { map { $_->{$key} => $_ } @{$csv->getline_hr_all ($fh)} } + $key ? do { + my ($k, $j, @f) = ref $key ? (undef, @$key) : ($key); + if (my @mk = grep { !exists $h{$_} } grep { defined } $k, @f) { + croak ($csv->_SetDiagInfo (4001, join ", " => @mk)); + } + +{ map { + my $r = $_; + my $K = defined $k ? $r->{$k} : join $j => @{$r}{@f}; + ( $K => ( + $val + ? ref $val + ? { map { $_ => $r->{$_} } @$val } + : $r->{$val} + : $r )); + } @{$csv->getline_hr_all ($fh)} } + } : $csv->getline_hr_all ($fh); } : # aoa @@ -1721,7 +1761,7 @@ $self->__cache_show_char(escape_char => $cache->{escape_char}); $self->__cache_show_char(sep_char => $cache->{sep}); for (qw/ - binary decode_utf8 allow_loose_escapes allow_loose_quotes + binary decode_utf8 allow_loose_escapes allow_loose_quotes allow_unquoted_escape allow_whitespace always_quote quote_empty quote_space escape_null quote_binary auto_diag diag_verbose formula strict has_error_input blank_is_undef empty_is_undef has_ahead @@ -2874,33 +2914,39 @@ =head1 SYNOPSIS +This section is taken from Text::CSV_XS. + + # Functional interface + use Text::CSV_PP qw( csv ); + + # Read whole file in memory + my $aoa = csv (in => "data.csv"); # as array of array + my $aoh = csv (in => "data.csv", + headers => "auto"); # as array of hash + + # Write array of arrays as csv file + csv (in => $aoa, out => "file.csv", sep_char=> ";"); + + # Only show lines where "code" is odd + csv (in => "data.csv", filter => { code => sub { $_ % 2 }}); + + # Object interface use Text::CSV_PP; - $csv = Text::CSV_PP->new(); # create a new object - # If you want to handle non-ascii char. - $csv = Text::CSV_PP->new({binary => 1}); - - $status = $csv->combine(@columns); # combine columns into a string - $line = $csv->string(); # get the combined string - - $status = $csv->parse($line); # parse a CSV string into fields - @columns = $csv->fields(); # get the parsed fields - - $status = $csv->status (); # get the most recent status - $bad_argument = $csv->error_input (); # get the most recent bad argument - $diag = $csv->error_diag (); # if an error occurred, explains WHY - - $status = $csv->print ($io, $colref); # Write an array of fields - # immediately to a file $io - $colref = $csv->getline ($io); # Read a line from file $io, - # parse it and return an array - # ref of fields - $csv->column_names (@names); # Set column names for getline_hr () - $ref = $csv->getline_hr ($io); # getline (), but returns a hashref - $eof = $csv->eof (); # Indicate if last parse or - # getline () hit End Of File + my @rows; + # Read/parse CSV + my $csv = Text::CSV_PP->new ({ binary => 1, auto_diag => 1 }); + open my $fh, "<:encoding(utf8)", "test.csv" or die "test.csv: $!"; + while (my $row = $csv->getline ($fh)) { + $row->[2] =~ m/pattern/ or next; # 3rd field should match + push @rows, $row; + } + close $fh; - $csv->types(\@t_array); # Set column types + # and write as CSV + open $fh, ">:encoding(utf8)", "new.csv" or die "new.csv: $!"; + $csv->say ($fh, $_) for @rows; + close $fh or die "new.csv: $!"; =head1 DESCRIPTION @@ -3018,7 +3064,7 @@ =head1 METHODS -This section is taken from Text::CSV_XS. +This section is also taken from Text::CSV_XS. =head2 version @@ -3528,6 +3574,8 @@ This attribute is useful when exporting CSV data to be imported in custom loaders, like for MySQL, that recognize special sequences for C<NULL> data. +This attribute has no meaning when parsing CSV data. + =head3 verbatim my $csv = Text::CSV_PP->new ({ verbatim => 1 }); @@ -3604,6 +3652,8 @@ escape_null => 1, quote_binary => 1, keep_meta_info => 0, + strict => 0, + formula => 0, verbatim => 0, undef_str => undef, types => undef, @@ -4589,9 +4639,12 @@ =head3 key If passed, will default L<C<headers>|/headers> to C<"auto"> and return a -hashref instead of an array of hashes. +hashref instead of an array of hashes. Allowed values are simple scalars or +array-references where the first element is the joiner and the rest are the +fields to join to combine the key. my $ref = csv (in => "test.csv", key => "code"); + my $ref = csv (in => "test.csv", key => [ ":" => "code", "color" ]); with test.csv like @@ -4600,7 +4653,7 @@ 2,keyboard,12,white 3,mouse,5,black -will return +the first example will return { 1 => { code => 1, @@ -4622,6 +4675,28 @@ } } +the second example will return + + { "1:gray" => { + code => 1, + color => 'gray', + price => 850, + product => 'pc' + }, + "2:white" => { + code => 2, + color => 'white', + price => 12, + product => 'keyboard' + }, + "3:black" => { + code => 3, + color => 'black', + price => 5, + product => 'mouse' + } + } + The C<key> attribute can be combined with L<C<headers>|/headers> for C<CSV> date that has no header line, like @@ -4631,6 +4706,76 @@ key => "c_foo", ); +=head3 value + +Used to create key-value hashes. + +Only allowed when C<key> is valid. A C<value> can be either a single column +label or an anonymous list of column labels. In the first case, the value +will be a simple scalar value, in the latter case, it will be a hashref. + + my $ref = csv (in => "test.csv", key => "code", + value => "price"); + my $ref = csv (in => "test.csv", key => "code", + value => [ "product", "price" ]); + my $ref = csv (in => "test.csv", key => [ ":" => "code", "color" ], + value => "price"); + my $ref = csv (in => "test.csv", key => [ ":" => "code", "color" ], + value => [ "product", "price" ]); + +with test.csv like + + code,product,price,color + 1,pc,850,gray + 2,keyboard,12,white + 3,mouse,5,black + +the first example will return + + { 1 => 850, + 2 => 12, + 3 => 5, + } + +the second example will return + + { 1 => { + price => 850, + product => 'pc' + }, + 2 => { + price => 12, + product => 'keyboard' + }, + 3 => { + price => 5, + product => 'mouse' + } + } + +the third example will return + + { "1:gray" => 850, + "2:white" => 12, + "3:black" => 5, + } + +the fourth example will return + + { "1:gray" => { + price => 850, + product => 'pc' + }, + "2:white" => { + price => 12, + product => 'keyboard' + }, + "3:black" => { + price => 5, + product => 'mouse' + } + } + =head3 keep_headers When using hashes, keep the column names into the arrayref passed, so all @@ -5188,6 +5333,16 @@ The C<key> attribute is of an unsupported type. =item * +1502 "PRM - The value attribute is passed without the key attribute" + +The C<value> attribute is only allowed when a valid key is given. + +=item * +1503 "PRM - The value attribute is passed as an unsupported type" + +The C<value> attribute is of an unsupported type. + +=item * 2010 "ECR - QUO char inside quotes followed by CR not part of EOL" When L<C<eol>|/eol> has been set to anything but the default, like diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV-1.97/t/66_formula.t new/Text-CSV-1.99/t/66_formula.t --- old/Text-CSV-1.97/t/66_formula.t 2018-08-14 13:38:11.000000000 +0200 +++ new/Text-CSV-1.99/t/66_formula.t 2019-01-02 12:47:34.000000000 +0100 @@ -39,7 +39,7 @@ foreach my $f (-1, 9, "xxx", "DIAX", [], {}, sub {}) { eval { $csv->formula ($f); }; - like ($@, qr/^formula-handling '\Q$f\E' is not supported/, "$f in invalid"); + like ($@, qr/\bformula-handling '\Q$f\E' is not supported/, "$f in invalid"); } my %f = qw( @@ -55,7 +55,7 @@ is ($p->formula, $f{$f}, "Set to $f{$f}"); } eval { Text::CSV->new ({ formula => "xxx" }); }; -like ($@, qr/^formula-handling 'xxx' is not supported/, "xxx in invalid"); +like ($@, qr/\bformula-handling 'xxx' is not supported/, "xxx is invalid"); # Parser diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV-1.97/t/80_diag.t new/Text-CSV-1.99/t/80_diag.t --- old/Text-CSV-1.97/t/80_diag.t 2018-08-14 13:38:11.000000000 +0200 +++ new/Text-CSV-1.99/t/80_diag.t 2019-01-02 12:47:34.000000000 +0100 @@ -3,7 +3,7 @@ use strict; $^W = 1; - use Test::More tests => 288; + use Test::More tests => 303; #use Test::More "no_plan"; my %err; @@ -280,4 +280,30 @@ } } +SKIP: { + $] < 5.008 and skip qq{$] does not support ScalarIO}, 14; + foreach my $key ({}, sub {}, []) { + my $csv = Text::CSV->new; + my $x = eval { $csv->csv (in => \"a,b", key => $key) }; + is ($x, undef, "Invalid key"); + my @diag = $csv->error_diag; + is ($diag[0], 1501, "Invalid key type"); + } + + { my $csv = Text::CSV->new; + my $x = eval { $csv->csv (in => \"a,b", value => "b") }; + is ($x, undef, "Value without key"); + my @diag = $csv->error_diag; + is ($diag[0], 1502, "No key"); + } + + foreach my $val ({}, sub {}, []) { + my $csv = Text::CSV->new; + my $x = eval { $csv->csv (in => \"a,b", key => "a", value => $val) }; + is ($x, undef, "Invalid value"); + my @diag = $csv->error_diag; + is ($diag[0], 1503, "Invalid value type"); + } + } + 1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV-1.97/t/85_util.t new/Text-CSV-1.99/t/85_util.t --- old/Text-CSV-1.97/t/85_util.t 2018-08-14 13:38:11.000000000 +0200 +++ new/Text-CSV-1.99/t/85_util.t 2019-01-02 12:47:34.000000000 +0100 @@ -14,7 +14,7 @@ plan skip_all => "This test unit requires perl-5.8.2 or higher"; } else { - my $n = 1370; + my $n = 1442; $pu and $n -= 120; plan tests => $n; } @@ -279,7 +279,7 @@ $csv = Text::CSV->new ({ binary => 1, auto_diag => 9 }); SKIP: { - $has_enc or skip "Encoding $enc not supported", 7; + $has_enc or skip "Encoding $enc not supported", $enc =~ /^utf/ ? 10 : 9; $csv->column_names (undef); open my $fh, "<", $fnm; binmode $fh; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV-1.97/t/90_csv.t new/Text-CSV-1.99/t/90_csv.t --- old/Text-CSV-1.97/t/90_csv.t 2018-08-14 13:38:11.000000000 +0200 +++ new/Text-CSV-1.99/t/90_csv.t 2019-01-02 12:47:34.000000000 +0100 @@ -5,7 +5,7 @@ use Config; #use Test::More "no_plan"; - use Test::More tests => 88; + use Test::More tests => 105; BEGIN { $ENV{PERL_TEXT_CSV} = 0; @@ -117,11 +117,35 @@ # Basic "key" checks SKIP: { - $] < 5.008 and skip "No ScalarIO support for $]", 2; + $] < 5.008 and skip "No ScalarIO support for $]", 4; + # Simple key is_deeply (csv (in => \"key,value\n1,2\n", key => "key"), { 1 => { key => 1, value => 2 }}, "key"); is_deeply (csv (in => \"1,2\n", key => "key", headers => [qw( key value )]), { 1 => { key => 1, value => 2 }}, "key"); + # Combined key + is_deeply (csv (in => \"a,b,value\n1,1,2\n", key => [ ":" => "a", "b" ]), + { "1:1" => { a => 1, b => 1, value => 2 }}, "key list"); + is_deeply (csv (in => \"2,3,2\n", key => [ ":" => "a", "b" ], headers => [qw( a b value )]), + { "2:3" => { a => 2, b => 3, value => 2 }}, "key list"); + } +# Basic "value" checks +SKIP: { + $] < 5.008001 and skip "No ScalarIO support for 'value's in $]", 5; + # Simple key simple value + is_deeply (csv (in => \"key,value\n1,2\n", key => "key", value => "value"), + { 1 => 2 }, "key:value"); + is_deeply (csv (in => \"1,2\n", key => "key", headers => [qw( key value )], value => "value"), + { 1 => 2 }, "key:value"); + # Simple key combined value + is_deeply (csv (in => \"key,v1,v2\n1,2,3\n", key => "key", value => [ "v1", "v2" ]), + { 1 => { v1 => 2, v2 => 3 }}, "key:value"); + # Combined key simple value + is_deeply (csv (in => \"a,b,value\n1,1,2\n", key => [ ":" => "a", "b" ], value => "value"), + { "1:1" => 2 }, "[key]:value"); + # Combined key combined value + is_deeply (csv (in => \"a,b,v1,v2\n1,1,2,2\n", key => [ ":" => "a", "b" ], value => [ "v1", "v2" ]), + { "1:1" => { v1 => 2, v2 => 2 }}, "[key]:[value]"); } # Some "out" checks @@ -164,24 +188,56 @@ $] < 5.008 and unlink glob "SCALAR(*)"; # errors -{ my $err; +{ my $err = ""; local $SIG{__DIE__} = sub { $err = shift; }; my $r = eval { csv (in => undef); }; is ($r, undef, "csv needs in or file"); like ($err, qr{^usage:}, "error"); - undef $err; + $err = ""; - $r = eval { csv (in => $tfn, key => ["foo"], auto_diag => 0); }; - is ($r, undef, "Fail call with bad key type"); - like ($err, qr{1501 - PRM}, "Error 1501"); - undef $err; + $r = eval { csv (in => $tfn, key => [ ":" ], auto_diag => 0); }; + $err =~ s{\s+at\s+\S+\s+line\s+\d+\.\r?\n?\Z}{}; + is ($r, undef, "Fail call with key with not enough fields"); + like ($err, qr{PRM.*unsupported type}, $err); + $err = ""; + + $r = eval { csv (in => $tfn, key => { "fx" => 1 }, auto_diag => 0); }; + $err =~ s{\s+at\s+\S+\s+line\s+\d+\.\r?\n?\Z}{}; + is ($r, undef, "Fail call with unsupported key type"); + like ($err, qr{PRM.*unsupported type}, $err); + $err = ""; + + $r = eval { csv (in => $tfn, key => sub { "foo" }, auto_diag => 0); }; + $err =~ s{\s+at\s+\S+\s+line\s+\d+\.\r?\n?\Z}{}; + is ($r, undef, "Fail call with bad unsupported type"); + like ($err, qr{PRM.*unsupported type}, $err); + $err = ""; + + $r = eval { csv (in => $tfn, key => "xyz", auto_diag => 0); }; + $err =~ s{\s+at\s+\S+\s+line\s+\d+\.\r?\n?\Z}{}; + is ($r, undef, "Fail call with nonexisting key"); + like ($err, qr{PRM.*xyz}, $err); + $err = ""; + + $r = eval { csv (in => $tfn, key => [ "x" ], auto_diag => 0); }; + $err =~ s{\s+at\s+\S+\s+line\s+\d+\.\r?\n?\Z}{}; + is ($r, undef, "Fail call with no key in keylist"); + like ($err, qr{PRM.*unsupported type}, $err); + $err = ""; + + $r = eval { csv (in => $tfn, key => [ ":", "a", "xyz" ], auto_diag => 0); }; + $err =~ s{\s+at\s+\S+\s+line\s+\d+\.\r?\n?\Z}{}; + is ($r, undef, "Fail call with nonexisting key in keylist"); + like ($err, qr{PRM.*xyz}, $err); + $err = ""; local $SIG{__DIE__} = sub { $err = shift; }; foreach my $hr (1, "foo", \my %hr, sub { 42; }, *STDOUT) { $r = eval { csv (in => $tfn, kh => $hr, auto_diag => 0); }; + $err =~ s{\s+at\s+\S+\s+line\s+\d+\.\r?\n?\Z}{}; is ($r, undef, "Fail call with bad keep_header type"); - like ($err, qr{1501 - PRM}, "Error 1501"); - undef $err; + like ($err, qr{PRM.*unsupported type}, $err); + $err = ""; } # $r = eval { csv (in => +{}, auto_diag => 0); }; @@ -190,42 +246,49 @@ # undef $err; $r = eval { csv (in => undef, auto_diag => 0); }; + $err =~ s{\s+at\s+\S+\s+line\s+\d+\.\r?\n?\Z}{}; is ($r, undef, "Cannot read from undef"); like ($err, qr{^usage}, "Remind them of correct syntax"); - undef $err; + $err = ""; $r = eval { csv (in => "", auto_diag => 0); }; + $err =~ s{\s+at\s+\S+\s+line\s+\d+\.\r?\n?\Z}{}; is ($r, undef, "Cannot read from empty"); like ($err, qr{^usage}, "Remind them of correct syntax"); - undef $err; + $err = ""; my $fn = "./dev/foo/bar/\x99\x99/\x88\x88/". (join "\x99" => map { chr (128 + int rand 128) } 0..100).".csv"; $r = eval { csv (in => $fn, auto_diag => 0); }; + $err =~ s{\s+at\s+\S+\s+line\s+\d+\.\r?\n?\Z}{}; is ($r, undef, "Cannot read from impossible file"); like ($err, qr{/foo/bar}, "No such file or directory"); - undef $err; + $err = ""; $r = eval { csv (in => [[1,2]], out => $fn, auto_diag => 0); }; + $err =~ s{\s+at\s+\S+\s+line\s+\d+\.\r?\n?\Z}{}; is ($r, undef, "Cannot write to impossible file"); like ($err, qr{/foo/bar}, "No such file or directory"); - undef $err; + $err = ""; my %x; $r = eval { csv (in => $tfn, out => \%x, auto_diag => 0); }; + $err =~ s{\s+at\s+\S+\s+line\s+\d+\.\r?\n?\Z}{}; is ($r, undef, "Cannot write to hashref"); like ($err, qr{Not a GLOB}i, "Not a GLOB"); - undef $err; + $err = ""; $r = eval { csv (); }; + $err =~ s{\s+at\s+\S+\s+line\s+\d+\.\r?\n?\Z}{}; is ($r, undef, "Needs arguments"); like ($err, qr{^usage}i, "Don't know what to do"); - undef $err; + $err = ""; $r = eval { csv (in => "in.csv", out => "out.csv"); }; + $err =~ s{\s+at\s+\S+\s+line\s+\d+\.\r?\n?\Z}{}; is ($r, undef, "Cannot use strings for both"); like ($err, qr{^cannot}i, "Explicitely unsupported"); - undef $err; + $err = ""; } eval {
