This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
new perldelta
[perl5.git] / ext / B / t / terse.t
CommitLineData
3a5d7bb8
JH
1#!./perl
2
3BEGIN {
74517a3a 4 unshift @INC, 't';
9cd8f857
NC
5 require Config;
6 if (($Config::Config{'extensions'} !~ /\bB\b/) ){
7 print "1..0 # Skip -- Perl configured without B module\n";
8 exit 0;
9 }
3a5d7bb8
JH
10}
11
31b49ad4 12use Test::More tests => 16;
3a5d7bb8
JH
13
14use_ok( 'B::Terse' );
15
16# indent should return a string indented four spaces times the argument
1212f7d8
JH
17is( B::Terse::indent(2), ' ' x 8, 'indent with an argument' );
18is( B::Terse::indent(), '', 'indent with no argument' );
3a5d7bb8
JH
19
20# this should fail without a reference
21eval { B::Terse::terse('scalar') };
1212f7d8 22like( $@, qr/not a reference/, 'terse() fed bad parameters' );
3a5d7bb8
JH
23
24# now point it at a sub and see what happens
25sub foo {}
26
27my $sub;
28eval{ $sub = B::Terse::compile('', 'foo') };
1212f7d8
JH
29is( $@, '', 'compile()' );
30ok( defined &$sub, 'valid subref back from compile()' );
3a5d7bb8
JH
31
32# and point it at a real sub and hope the returned ops look alright
33my $out = tie *STDOUT, 'TieOut';
34$sub = B::Terse::compile('', 'bar');
35$sub->();
36
37# now build some regexes that should match the dumped ops
38my ($hex, $op) = ('\(0x[a-f0-9]+\)', '\s+\w+');
39my %ops = map { $_ => qr/$_ $hex$op/ }
31b49ad4 40 qw ( OP COP LOOP PMOP UNOP BINOP LOGOP LISTOP PVOP );
3a5d7bb8
JH
41
42# split up the output lines into individual ops (terse is, well, terse!)
43# use an array here so $_ is modifiable
44my @lines = split(/\n+/, $out->read);
45foreach (@lines) {
46 next unless /\S/;
47 s/^\s+//;
48 if (/^([A-Z]+)\s+/) {
49 my $op = $1;
50 next unless exists $ops{$op};
1212f7d8 51 like( $_, $ops{$op}, "$op " );
3a5d7bb8 52 s/$ops{$op}//;
5638aaac 53 delete $ops{$op};
3a5d7bb8
JH
54 redo if $_;
55 }
56}
57
58warn "# didn't find " . join(' ', keys %ops) if keys %ops;
59
60# XXX:
61# this tries to get at all tersified optypes in B::Terse
31b49ad4
SM
62# if you can think of a way to produce AV, NULL, PADOP, or SPECIAL,
63# add it to the regex above too. (PADOPs are currently only produced
64# under ithreads, though).
3a5d7bb8 65#
fd55ca4f 66our ( $a, $b );
3a5d7bb8
JH
67sub bar {
68 # OP SVOP COP IV here or in sub definition
69 my @bar = (1, 2, 3);
70
71 # got a GV here
72 my $foo = $a + $b;
73
74 # NV here
75 $a = 1.234;
76
77 # this is awful, but it gives a PMOP
5638aaac 78 our @ary = split('', $foo);
3a5d7bb8 79
31b49ad4 80 # PVOP, LOOP
3a5d7bb8
JH
81 LOOP: for (1 .. 10) {
82 last LOOP if $_ % 2;
83 }
84
85 # make a PV
86 $foo = "a string";
f3be9b72
RGS
87
88 # make an OP_SUBSTCONT
89 $foo =~ s/(a)/$1/;
3a5d7bb8
JH
90}
91
31b49ad4
SM
92# Schwern's example of finding an RV
93my $path = join " ", map { qq["-I$_"] } @INC;
07a63b99 94my $items = qx{$^X $path "-MO=Terse" -le "print \\42" 2>&1};
eb32218e 95like( $items, qr/IV $hex \\42/, 'RV (but now stored in an IV)' );
3a5d7bb8
JH
96
97package TieOut;
98
99sub TIEHANDLE {
100 bless( \(my $out), $_[0] );
101}
102
103sub PRINT {
104 my $self = shift;
105 $$self .= join('', @_);
106}
107
108sub PRINTF {
109 my $self = shift;
110 $$self .= sprintf(@_);
111}
112
113sub read {
114 my $self = shift;
115 return substr($$self, 0, length($$self), '');
116}