qr{((?>\\[^\\])|"(?:\\\\"|[^\\"]*)"|(?:'[^\\']*'|\S+))+} #### # ln#, ans, test text 1 3,This is simple. 2 3,This is "so very simple". 3 4,This "is so" very simple. 4 2,This 'isn\'t nice.' 5 2,This "isn\"t nice." 6 3,This 'isn\\'t nice.' 7 3,This "isn\\"t nice." 8 2,This "isnt wrong." 9 2,This 'isnt wrong.' 10 3,This 'isn\\'t wrong. 11 3,This "isn\\"t wrong. 12 3,This isn\'t horrible. 13 3,This isn\"t terrible. 14 3,This \"isnt unnice.\" 15 3,This \'isnt unnice.\' 16 2,This 'is not unnice.' 17 2,This "is not unnice." 18 3,a "bb cc" d #### ResByLn:{ln=>1, wanted=>3, got=>[3]},[" p "] ResByLn:{ln=>2, wanted=>3, got=>[3]},[" p "] ResByLn:{ln=>3, wanted=>4, got=>[4]},[" p "] ResByLn:{ln=>4, wanted=>2, got=>[3]},["FAIL:"] ResByLn:{ln=>5, wanted=>2, got=>[3]},["FAIL:"] ResByLn:{ln=>6, wanted=>3, got=>[3]},[" p "] ResByLn:{ln=>7, wanted=>3, got=>[3]},[" p "] ResByLn:{ln=>8, wanted=>2, got=>[2]},[" p "] ResByLn:{ln=>9, wanted=>2, got=>[2]},[" p "] ResByLn:{ln=>10, wanted=>3, got=>[3]},[" p "] ResByLn:{ln=>11, wanted=>3, got=>[3]},[" p "] ResByLn:{ln=>12, wanted=>3, got=>[3]},[" p "] ResByLn:{ln=>13, wanted=>3, got=>[3]},[" p "] ResByLn:{ln=>14, wanted=>3, got=>[3]},[" p "] ResByLn:{ln=>15, wanted=>3, got=>[3]},[" p "] ResByLn:{ln=>16, wanted=>2, got=>[2]},[" p "] ResByLn:{ln=>17, wanted=>2, got=>[2]},[" p "] ResByLn:{ln=>18, wanted=>3, got=>[3]},[" p "] #### #!/usr/bin/perl use P; # vim=:SetNumberAndWidth if ( -t 0) { # unlikely to provide reliable test case open(STDIN, "<&=", "main::DATA") || die "opening internal tests: $!"; } my @lines = grep { defined $_ and ! /^\s*#/ } (); my @regex = ( qr{((?>\\[^\\])|"(?:\\\\"|[^\\"]*)"|(?:'[^\\']*'|\S+))+} ); my $ln=0; my $norm=0; my @ResByLn; sub lnout($$$) { my ($ans,$outp, $lnp) = @_; bless {wanted=>$ans, got=>$outp, ln=>$lnp}, q(ResByLn:); } sub txt($) { local $_=shift; my (undef, undef,$txt)=m{^\s*(\d+)\s+(\d+),(.*)}; $txt; } my $only_fails = @ARGV && $ARGV[0] eq '-f' ? 1 : 0; for (@lines) { ++$ln; my ($lnnum, $ans,$_)=m{^\s*(\d+)\s+(\d+),(.*)}; my @got; for (my $r=0; $r<@regex; ++$r) { my $reg = $regex[$r]; my @out = grep {$_ } m{$reg}g; my $cnt = 0+@out; push @got, $cnt; } $lnnum and push @outs, lnout($ans, \@got, $lnnum); } for my $o (@outs) { my $ans = $o->{wanted}; my @out = @{$o->{got}}; my $ln = $o->{ln}; my @rts; #results for (my $i=0;$i<@out;++$i) { $rts[$i] = do { if ($ans==$out[$i]) { " p " } else { "FAIL:" . do { my $txt = txt($lines[$ln]); chomp $txt; "<$txt>"; }; } }; } my @output_args=("%s,%s",$o,\@rts); # * Shows line-number, result-wanted, result-got + test-status # * if test-status is FAIL, shows corresponding test-txt between <> (carats) # unless ($only_fails) { P @output_args; } else { my @fails = grep /FAIL/, P @output_args; foreach (@fails) { P "%s", $_; } } } # vim: ts=2 sw=2 ai number __DATA__ # ln#, ans, test text 1 3,This is simple. 2 3,This is "so very simple". 3 4,This "is so" very simple. 4 2,This 'isn\'t nice.' 5 2,This "isn\"t nice." 6 3,This 'isn\\'t nice.' 7 3,This "isn\\"t nice." 8 2,This "isnt wrong." 9 2,This 'isnt wrong.' 10 3,This 'isn\\'t wrong. 11 3,This "isn\\"t wrong. 12 3,This isn\'t horrible. 13 3,This isn\"t terrible. 14 3,This \"isnt unnice.\" 15 3,This \'isnt unnice.\' 16 2,This 'is not unnice.' 17 2,This "is not unnice." 18 3,a "bb cc" d __END__