App-pltest
view release on metacpan or search on metacpan
$q, $quote,
$Q, $Quote,
$R, $RESULT,
@R, @RESULT,
%R, %RESULT,
$T, $TXT_SORT );
# Echo remove quine
sub echo(@) {
if( wantarray ) {
my @ret = &Echo;
$ret[-1] .= "\n" if @ret;
@ret;
} elsif( defined wantarray ) {
join( ' ', &Echo ) . "\n";
} else {
local $, = ' ';
say &Echo;
}
}
# Echo without newline
sub Echo(@) {
if( wantarray ) {
map {
if( ! defined ) {
"$pltest::c{I}undef$pltest::c{E}";
} elsif( !ref ) {
$_;
} elsif( eval { $_->can( '(""' ) } ) {
"$_";
} else {
require Data::Dumper;
} @_ ? @_ : $_;
} elsif( defined wantarray ) {
join ' ', &Echo;
} else {
local( $,, $\, $| ) = (' ', '', 1);
print &Echo;
}
}
# Would call it format, but that's not overridable.
sub form($@) {
echo &Form;
}
# Form without newline
sub Form($@) {
(my $form = shift) =~ s/%\K(%|[^a-z]+)/ my $x = $1; $x =~ tr!:!$!; $x /eg; # also matches %%, todo /r
Echo sprintf $form, &Echo;
}
sub benchmark(&@) {
my( $code, $name, @args ) = @_;
local( $a, $b ) = ($a, $b);
$name //= 'anonymous';
require Benchmark;
local $SIG{__WARN__} = sub { die @_ };
if( @args ) {
say Benchmark::timestr( Benchmark::countit( 10, $code )), " $name: $_"
for @args;
} else {
say Benchmark::timestr( Benchmark::countit( 10, $code )), " $name";
}
}
# Do it 100x for very fast test code (to increase weight compared to Benchmark overhead).
sub Benchmark(&@) {
my( $code, @rest ) = @_;
benchmark { for my $i (0..99) { &$code() }} @rest;
}
sub Config(@) {
require Config;
if( @_ ) {
#{map { pairgrep { $a =~ /$_/ } %Config::Config } @_}; # needs 5.20
my %config;
while( my( $k, $v ) = each %Config::Config ) {
$k =~ $_ and $config{$k} = $v, last
for @_;
}
\%config;
} else {
\%Config::Config;
}
}
sub Date(@) {
my( $s, $us, $tz, $tzo );
require Time::HiRes;
for( @_ ) {
if( ref ) {
($s, $us) = @$_;
} elsif( /^([-+]?)(1[0-4]|0?[0-9])(?:\.([0-9])([0-9])?|:([0-5])?([0-9]))?$/i ) {
$tz = $2 * 3600 + ($3 ? ($3.($4//0)) * 36 : $6 ? (($5//0).$6) * 60 : 0);
$tzo = sprintf ' %s%02d:%02d', $1 || '+', $tz / 3600, $tz % 3600 / 60;
$tz = -$tz if $1 eq '-';
} elsif( /^([-+]?)(?=.)([0-9]*)(?:\.([0-9]*))?$/i ) {
my @time = reverse +(defined( $tz ) ? gmtime $s + $tz : localtime $s)[0..5];
$s = sprintf '%04d-%02d-%02dT%02d:%02d:%02d.%06d%s', 1900 + shift( @time ), 1 + shift( @time ), @time, $us, $tzo // '';
} else {
$s = defined( $tz ) ? gmtime $s + $tz : localtime $s;
substr $s, 19, 0, $tzo if $tzo;
substr $s, 19, 0, sprintf '.%06d', $us // 0;
}
defined wantarray ? $s : say $s;
}
sub Isodate(@) {
local $pltest::isodate = 1;
&Date;
}
# turns list of ipv4/6 addresses & hostnames or $_ into /etc/hosts format
# todo comment not found
sub hosts(@) {
require Socket;
package Socket;
my( %res, %name );
my $res = sub {
my( $v4, $name, $aliases, undef, undef, @addr ) = @_;
undef $name{$_} for $name, split ' ', $aliases;
for( @addr ) {
$_ = unpack 'H*', $_;
if( $v4 ) { # make sortable by kind
s/^(?=7f)/g/ or # loopback
}
for( sort keys %res ) {
next if 1 == length; # IPv6 on old perl
my $ip = pack 'H*', substr $_, 1;
::echo 4 == length $ip ? inet_ntoa( $ip ) : inet_ntop( AF_INET6(), $ip ),
sort grep ! /^[0-9.]+$|^(?=.*:)[0-9a-f:]+$/i, keys %{$res{$_}};
}
}
# Fill keydiff arrays
sub keydiff(;$$) {
my $val;
if( @_ > 1 ) {
$val = $_[1];
} else {
chomp( $val = $_ );
}
$KEYDIFF{@_ == 0 ? $1 : $_[0]}[$ARGIND] = $val;
}
sub Keydiff(;$$) {
my $key = $FIELD[@_ == 0 ? 0 : $_[0]];
if( @_ > 1 ) {
keydiff $key, $_[1];
} else {
keydiff $key;
}
}
# trim small values from %NUMBER
sub Number(;$) {
my $n = $_[0] // 2;
$NUMBER{$_} < $n and delete $NUMBER{$_} for keys %NUMBER;
}
# Pipe command to CODE
sub piped(&$@) {
my $code = shift;
open my $fd, "-|", @_ or die "$_[0]: $!\n";
&$code() while <$fd>;
}
sub help(;$) {
if( @_ && ! defined $_[0] ) {
print <<\EOF;
usage: pltest {-{BbeE} program} [-o] [-Vversion] [-perlopt...] [--] [main program] [arg ...]
-Aprog map prog over @A (or undef) returning new @A
-bprog & -eprog wrap begin/end program around each file in -n/-p...
-Bprog & -Eprog wrap begin/end program around program in same scope, my-vars work
-o[number] assume "for(@A) { ... }" loop around main program or array of number args
-O[number] like -o, but use $A as loop var
-p[number] print on each loop (also -o/-O) iteration, at most number times
-P[number] like -p, but print only if main program evaluates to true, like grep
use strict;
use Test::Simple tests => 8;
# chdir to t/
$_ = $0;
s~[^/\\]+$~~;
chdir $_ if length;
# run pltest, expect $_
sub pltest(@) {
my $fh;
if( $^O =~ /^MSWin/ ) {
require Win32::ShellQuote;
open $fh, Win32::ShellQuote::quote_native( $^X, '-W', '..\pltest', @_ ) . '|';
} else {
open $fh, '-|', $^X, '-W', '../pltest', @_;
}
local $/;
my $ret = <$fh>;
ok $ret eq $_, join ' ', 'pltest', map /[\s*?()[\]{}\$\\'";|&]|^$/ ? "'$_'" : $_, @_
or print "got: '$ret', expected: '$_'\n";
}
# run pltest, expect $_ altered by shift->()
sub pl_a(&@) {
local $_ = $_;
shift->();
&pltest;
}
my @files = <atom-weight-[123].csv>;
my( $B, $I, $G, $R, $E ) = map "\e[${_}m", 1, 3, 32, 31, '', '';
# Run one with Algorithm::Diff, once without
#pltest -F, --color K *.csv | pltest -pB '@c{1, 3, 32, 31, ""} = qw(B I G R E)' 's/\e\[(\d*)m/\${$c{$1}}/g'
pltest @BbeE, 'E "$I;$A:$. $_"', @files;
pl_e '', '-n', '', @files;
unBbeE;
s/^.+? //gm;
$copy = $_;
# run pltest, expect @F[1, 0] separated by $_[0]
sub pl_F($$) {
my $sep = $_[0];
pl_a { s/^(.+)$sep(.+)$/$2$sep$1/gm } "-Bmy \$j = '$sep'", $_[1], '$_ = pop @F; e join $j, $_, @F', @files;
}
pl_F ' ', '-al';
pl_F ',', '-lF,';
pl_F ':', '-lF:';
s/.+?:[0-9]+ //mg; # reduce to only file contents
pltest '-n', 'E', @files;
t/sort_keys.t view on Meta::CPAN
use strict;
use Test::Simple tests => 12;
# chdir to t/
$_ = $0;
s~[^/\\]+$~~;
chdir $_ if length;
# run pltest, expect $_
sub pltest(@) {
my $fh;
if( $^O =~ /^MSWin/ ) {
require Win32::ShellQuote;
open $fh, Win32::ShellQuote::quote_native( $^X, '-W', '..\pltest', @_ ) . '|';
} else {
open $fh, '-|', $^X, '-W', '../pltest', @_;
}
local $/;
my $ret = <$fh>;
ok $ret eq $_, join ' ', 'pltest', map /[\s*?()[\]{}\$\\'";|&]|^$/ ? "'$_'" : $_, @_
or print "got: '$ret', expected: '$_'\n";
}
# run pltest, shift -B arg, sort list
sub pl_s($@) {
my( $B, @l ) = @_;
local $_ = join '',
map "$_: 0\n", @l;
pltest '-B', $B, '@R{@A} = (0) x @A', @l;
}
my @l = qw(0 07 08 a b c aa 0b1 0b2 bb be cc bad babe);
pl_s '', @l;
pl_s '$H = 1', sort { hex $a <=> hex $b } @l;
use warnings;
use strict;
use Test::Simple tests => $::tests;
use IPC::Open3;
sub slurp($) {
my( $ret, $n ) = '';
while( $n = sysread $_[0], my $txt, 1024 ) {
$ret .= $txt;
}
unless( defined $n ) {
$ret .= "sysread: $!";
}
$ret;
}
# run pltest, expect $_
sub pltest(@) {
my @cmd = ($^X, '-W', '../pltest', @_);
if( $^O =~ /^MSWin/ ) {
require Win32::ShellQuote;
$cmd[2] = '..\pltest';
@cmd = Win32::ShellQuote::quote_native( @cmd );
}
my $none = '';
my $pid = open3( $none, my $fh, '', @cmd );
my $ret = slurp $fh;
ok $ret eq $_,
join ' ', 'pltest', map /[\s*?()[\]{}\$\\'";|&]|^$/ ? "'$_'" : $_, @_
or print "got: '$ret', expected: '$_'\n";
waitpid $pid, 0;
}
# run pltest, expect shift
sub pl_e($@) {
local $_ = shift;
&pltest;
}
# run pltest, expect $_ altered by shift->()
sub pl_a(&@) {
local $_ = $_;
shift->();
&pltest;
}
1;
use strict;
use Test::Simple tests => 8;
# chdir to t/
$_ = $0;
s~[^/\\]+$~~;
chdir $_ if length;
# run pltest, expect $_
sub pltest(@) {
my $fh;
if( $^O =~ /^MSWin/ ) {
require Win32::ShellQuote;
open $fh, Win32::ShellQuote::quote_native( $^X, '-W', '..\pltest', @_ ) . '|';
} else {
open $fh, '-|', $^X, '-W', '../pltest', @_;
}
local $/;
my $ret = <$fh>;
ok $ret eq $_, join ' ', 'pltest', map /[\s*?()[\]{}\$\\'";|&]|^$/ ? "'$_'" : $_, @_
or print "got: '$ret', expected: '$_'\n";
}
# run pltest, expect shift
sub pl_e($@) {
local $_ = shift;
&pltest;
}
# Isodate, Date
my $fmt = '1973-11-29T21:33:09.%06d +00:00 'x3 . '1973-11-29T22:33:09.%06d +01:00 ' .
"Thu Nov 29 12:03:19.%06d -09:30 1973 Fri Nov 30 06:18:09.%06d +08:45 1973\n";
$_ = join '', map sprintf( $fmt, ($_)x6 ), 0, 0, 100_000, 1, 123_456, 123_456;
( run in 0.663 second using v1.01-cache-2.11-cpan-65fba6d93b7 )