Affix
view release on metacpan or search on metacpan
lib/Test2/Tools/Affix.pm view on Meta::CPAN
use Test2::API qw[context run_subtest];
use Test2::V0 -no_srand => 1, '!subtest';
use Test2::Util::Importer 'Test2::Tools::Subtest' => ( subtest_streamed => { -as => 'subtest' } );
use Test2::Plugin::UTF8;
use Test2::IPC;
use Path::Tiny qw[path tempfile];
use Exporter 'import';
use Capture::Tiny ':all';
our @CARP_NOT;
our %EXPORT_TAGS = (
all => [
our @EXPORT
= qw[
compile_ok affix_ok leaks
plan todo skip skip_all done_testing diag note
subtest ok isa_ok skip_all is isnt like
pass fail
lives dies try_ok warns warning
U D T F DNE array string float number bool hash etc end
refcount
can_ok isa_ok
capture imported_ok warns
path tempfile tempdir]
]
);
#
my $OS = $^O;
my $Inc = path($0)->absolute;
$Inc = $Inc->parent while !$Inc->child('t')->is_dir;
$Inc = $Inc->child( 't', 'src' );
my @cleanup;
END {
for my $file ( grep {-f} @cleanup ) {
unlink $file;
}
for my $dir ( grep {-d} @cleanup ) {
$dir->remove_tree;
}
}
#
sub compile_ok( $name, $aggs //= {}, $keep //= 0 ) {
my $c = context();
#~ return $c->pass_and_release($name) if 1;
#~ return $c->fail_and_release($name, @diag);
my ($opt) = grep { -f $_ } "t/src/$name.cxx", "t/src/$name.c", "src/$name.cxx", "src/$name.c";
if ($opt) {
$opt = path($opt)->absolute;
}
else {
$opt = tempfile(
UNLINK => !$keep,
SUFFIX => '_' . path( [ caller() ]->[1] )->basename . ( $name =~ m[^\s*//\s*ext:\s*\.c$]ms ? '.c' : '.cxx' )
)->absolute;
push @cleanup, $opt unless $keep;
my ( $package, $filename, $line ) = caller;
$filename = path($filename)->canonpath;
$line++;
$filename =~ s[\\][\\\\]g; # Windows...
$opt->spew_utf8(qq[#line $line "$filename"\r\n$name]);
}
if ( !$opt ) {
$c->fail('Failed to locate test source');
$c->release;
return ();
}
$aggs->{cflags} .= ' -I' . $Inc;
my $compiler = Affix::Build->new( debug => 0, name => 'testing', version => '1.0', flags => $aggs );
$compiler->add( $opt->canonpath );
$compiler->link;
push @cleanup, $opt->canonpath, $compiler->link unless $keep;
$c->ok( 1, 'build lib: ' . $compiler->link );
$c->release;
$compiler->link;
}
sub affix_ok ( $lib, $name, $args, $ret ) {
my $c = context;
my $sub;
diag __PACKAGE__;
diag join ', ', caller;
my $okay = run_subtest(
'affix ' . $name . '( ... )',
sub {
ok lives {
$sub = affix( $lib, $name, $args, $ret )
}, 'affix ' . $name . ' ...';
isa_ok $sub, ['Affix'], $name;
},
{ buffered => 0, no_fork => 1 }
);
$c->release;
return $sub;
}
{
my $supp; # defined later
my ( $test, $generate_suppressions, $count );
my $valgrind = 0;
my $file;
sub init_valgrind {
return if $valgrind;
require Path::Tiny;
$file = Path::Tiny::path($0)->absolute;
$valgrind = 1;
return plan skip_all 'Capture::Tiny is not installed' unless eval 'require Capture::Tiny';
return plan skip_all 'Path::Tiny is not installed' unless eval 'require Path::Tiny';
require Getopt::Long;
Getopt::Long::GetOptions( 'test=s' => \$test, 'generate' => \$generate_suppressions, 'count=i' => \$count );
Test2::API::test2_stack()->top->{count} = $count if defined $count;
if ( defined $test ) {
#~ Affix::set_destruct_level(3);
#~ die 'I should be running a test named ' . $test;
}
elsif ( defined $generate_suppressions ) {
no Test2::Plugin::ExitSummary;
pass 'exiting...';
done_testing;
lib/Test2/Tools/Affix.pm view on Meta::CPAN
$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;
}
for my $dir ( grep {-d} @cleanup ) {
#~ note 'Removing ' . $dir;
$dir->remove_tree;
}
}
};
1;
( run in 2.602 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )