Affix
view release on metacpan or search on metacpan
lib/Test2/Tools/Affix.pm view on Meta::CPAN
$_[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] ) {
$err =~ s[^((?:[ \t]*))(?=\S)][$1 ]gm;
print STDERR $err;
}
my $parsed = parse_xml( $report->slurp_utf8 );
# use Data::Dump;
# ddx $parsed;
# diag 'exit: '. $exit;
# Test2::API::test2_stack()->top->{count}++;
ok !$exit && !$parsed->{valgrindoutput}{errorcounts}, $name;
}
}
END {
for my $file ( grep {-f} @cleanup ) {
#~ note 'Removing ' . $file;
unlink $file;
( run in 0.715 second using v1.01-cache-2.11-cpan-39bf76dae61 )