Affix
view release on metacpan or search on metacpan
lib/Test2/Tools/Affix.pm view on Meta::CPAN
$l++;
next unless (/^\{/);
my $block = $_ . "\n";
while ( $_ = shift @in ) {
$l++;
$block .= $_ . "\n";
last if /^\}/;
}
$block // last;
if ( $block !~ /\}\n/ ) {
diag "Unterminated suppression at line $l";
last;
}
my $key = $block;
$key =~ s/(\A\{[^\n]*\n)\s*[^\n]*\n/$1/;
my $sum = Digest::MD5::md5_hex($key);
$dups++ if exists $known->{$sum};
$known->{$sum} = $block;
}
return ( $known, $dups );
}
sub dec_ent {
return $1 if $_[0] =~ m/^<!\[CDATA\[\{(.*)}]]>$/smg;
$_[0] =~ s[<][<]g;
$_[0] =~ s[>][>]g;
$_[0] =~ s[&][&]g;
shift;
}
sub stacktrace($blah) {
use Test2::Util::Table qw[table];
$blah ?
join "\n", table(
max_width => 120,
collapse => 1, # Do not show empty columns
header => [ 'function', 'path', 'line' ],
rows => [
map { [ $_->{fn}, ( defined $_->{dir} && defined $_->{file} ) ? join '/', $_->{dir}, $_->{file} : '', $_->{line} // '' ] } @$blah
],
) :
'';
}
sub parse_xml {
my ($xml) = @_;
my $hash = {};
my $re = qr{<([^>]+)>\s*(.*?)\s*</\1>}sm;
while ( $xml =~ m/$re/g ) {
my ( $tag, $content ) = ( $1, $2 );
$content = parse_xml($content) if $content =~ /$re/;
$content = dec_ent($content) unless ref $content;
if ( $tag eq 'error' ) {
# use Data::Dump;
# ddx $content;
diag $content->{what} // $content->{xwhat}{text};
if ( ref $content->{auxwhat} eq 'ARRAY' ) {
for my $i ( 0 .. scalar @{ $content->{stack} } ) {
note $content->{auxwhat}[$i] if $content->{auxwhat}[$i];
note stacktrace $content->{stack}[$i]{frame};
}
}
else {
note $content->{auxwhat};
for my $i ( 0 .. scalar @{ $content->{stack} } ) {
note stacktrace $content->{stack}[$i]{frame};
}
}
}
$hash->{$tag}
= defined $content ?
(
defined $hash->{$tag} ?
ref $hash->{$tag} eq 'ARRAY' ?
[ @{ $hash->{$tag} }, $content ] :
[ $hash->{$tag}, $content ] :
$tag =~ m/^(error|stack)$/ ? [$content] :
dec_ent($content) ) :
undef;
}
$hash;
}
# Function to run anonymous sub in a new process with valgrind
sub leaks( $name, $code_ref ) {
init_valgrind();
#
require B::Deparse;
CORE::state $deparse //= B::Deparse->new(qw[-l]);
my ( $package, $file, $line ) = caller;
my $source = sprintf
<<'', ( join ', ', map {"'$_'"} sort { length $a <=> length $b } grep {defined} map { my $dir = path($_); $dir->exists ? $dir->absolute->realpath : () } @INC, 't/lib' ), Test2::API::test2_stack()->top->{count}, $deparse->coderef2text(...
use lib %s;
use Test2::V0 -no_srand => 1, '!subtest';
use Test2::Util::Importer 'Test2::Tools::Subtest' => ( subtest_streamed => { -as => 'subtest' } );
use Test2::Plugin::UTF8;
no Test2::Plugin::ExitSummary; # I wish
use Test2::Tools::Affix;
# Test2::API::test2_stack()->top->{count} = %d;
$|++;
my $exit = sub {use Affix; Affix::set_destruct_level(3); %s;}->();
# Test2::API::test2_stack()->top->{count}++;
done_testing;
exit !$exit;
my $report = Path::Tiny->tempfile( { realpath => 1 }, 'valgrind_report_XXXXXXXXXX' );
push @cleanup, $report;
my @cmd = (
'valgrind', '-q', '--suppressions=' . $supp->canonpath,
'--leak-check=full', '--show-leak-kinds=all', '--show-reachable=yes', '--demangle=yes', '--error-limit=no', '--xml=yes',
'--gen-suppressions=all', '--xml-file=' . $report->stringify,
$^X, '-e', $source
);
my ( $out, $err, $exit ) = Capture::Tiny::capture(
sub {
system @cmd;
}
);
# $out =~ s[# Seeded srand with seed .+$][]m;
# $err =~ s[# Tests were run .+$][];
if ( $out =~ m[\S] ) {
$out =~ s[^((?:[ \t]*))(?=\S)][$1 ]gm;
print $out;
}
if ( $err =~ m[\S] ) {
( run in 1.271 second using v1.01-cache-2.11-cpan-df04353d9ac )