|
| 1 | +#!perl |
| 2 | +use warnings qw(all FATAL uninitialized); |
| 3 | +use strict; |
| 4 | +use Test::More tests => 14; |
| 5 | +use Test::Fatal; |
| 6 | +use Function::Parameters; |
| 7 | + |
| 8 | +BEGIN { |
| 9 | + package MyTC; |
| 10 | + |
| 11 | + method new( $class: |
| 12 | + :$incline = 0, |
| 13 | + :$file = undef, |
| 14 | + :$line = undef, |
| 15 | + :$broken = undef, |
| 16 | + ) { |
| 17 | + bless { |
| 18 | + incline => $incline, |
| 19 | + file => $file, |
| 20 | + line => $line, |
| 21 | + broken => $broken, |
| 22 | + }, $class |
| 23 | + } |
| 24 | + |
| 25 | + method can_be_inlined() { |
| 26 | + 1 |
| 27 | + } |
| 28 | + |
| 29 | + method inline_check($var) { |
| 30 | + my $line = $self->{line}; |
| 31 | + my $file = $self->{file}; |
| 32 | + if (defined $file) { |
| 33 | + $line //= (caller)[2]; |
| 34 | + } |
| 35 | + my $header = defined $line ? qq{#line $line "$file"\n} : ""; |
| 36 | + my $garbage = ";\n" x $self->{incline}; |
| 37 | + my $error = $self->{broken} ? "]" : ""; |
| 38 | + $header . "do { $garbage defined($var) $error }" |
| 39 | + } |
| 40 | + |
| 41 | + method check($value) { |
| 42 | + die "check() shouldn't be called"; |
| 43 | + } |
| 44 | + |
| 45 | + method get_message($value) { |
| 46 | + "value is not defined" |
| 47 | + } |
| 48 | +} |
| 49 | + |
| 50 | +use constant { |
| 51 | + TDef => MyTC->new, |
| 52 | + TBroken => MyTC->new(broken => 1, incline => 99), |
| 53 | + TDefI7 => MyTC->new(incline => 7), |
| 54 | + TDefX => MyTC->new(file => "fake-file", line => 666_666), |
| 55 | + TDefXI2 => MyTC->new(file => "fake-file", line => 666_666, incline => 2), |
| 56 | +}; |
| 57 | + |
| 58 | +is eval(qq|#line 2 "(virtual)"\nfun (TBroken \$bad) {}|), undef, "broken type constraint doesn't compile"; |
| 59 | +like $@, qr/\binlining type constraint MyTC=HASH\(\w+\) for parameter 1 \(\$bad\) failed at \(virtual\) line 2\b/, "broken type constraint reports correct source location"; |
| 60 | + |
| 61 | +#line 62 "t/types_inline.t" |
| 62 | +fun foo0(TDef $x) { $x } |
| 63 | + |
| 64 | +is foo0('good'), 'good', "defined value passes inline check"; |
| 65 | +like exception { foo0(undef) }, qr/\AIn fun foo0: parameter 1 \(\$x\): value is not defined\b/, "undefined value throws"; |
| 66 | +is __FILE__ . ' ' . __LINE__, "t/types_inline.t 66", "source location OK"; |
| 67 | + |
| 68 | +#line 69 "t/types_inline.t" |
| 69 | +fun foo1(TDefI7 $x) { $x } |
| 70 | + |
| 71 | +is foo1('good'), 'good', "(+7) defined value passes inline check"; |
| 72 | +like exception { foo1(undef) }, qr/\AIn fun foo1: parameter 1 \(\$x\): value is not defined\b/, "(+7) undefined value throws"; |
| 73 | +is __FILE__ . ' ' . __LINE__, "t/types_inline.t 73", "(+7) source location OK"; |
| 74 | + |
| 75 | +#line 76 "t/types_inline.t" |
| 76 | +fun foo2(TDefX $x) { $x } |
| 77 | + |
| 78 | +is foo2('good'), 'good', "(X) defined value passes inline check"; |
| 79 | +like exception { foo2(undef) }, qr/\AIn fun foo2: parameter 1 \(\$x\): value is not defined\b/, "(X) undefined value throws"; |
| 80 | +is __FILE__ . ' ' . __LINE__, "t/types_inline.t 80", "(X) source location OK"; |
| 81 | + |
| 82 | +#line 83 "t/types_inline.t" |
| 83 | +fun foo3(TDefXI2 $x) { $x } |
| 84 | + |
| 85 | +is foo3('good'), 'good', "(X+2) defined value passes inline check"; |
| 86 | +like exception { foo3(undef) }, qr/\AIn fun foo3: parameter 1 \(\$x\): value is not defined\b/, "(X+2) undefined value throws"; |
| 87 | +is __FILE__ . ' ' . __LINE__, "t/types_inline.t 87", "(X+2) source location OK"; |
0 commit comments