1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
|
#!perl -T
use strict;
use warnings;
use Test::More tests => 39 + (2 * 2 + 1) + (5 + 2 * 3);
use Variable::Magic qw<
wizard cast dispell
VMG_COMPAT_SCALAR_LENGTH_NOLEN VMG_COMPAT_SCALAR_NOLEN
>;
use lib 't/lib';
use Variable::Magic::TestValue;
my $c = 0;
my $n = 1 + int rand 1000;
my $d;
my $wiz = wizard len => sub { $d = $_[2]; ++$c; return $n };
is $c, 0, 'len: wizard() doesn\'t trigger magic';
my @a = qw<a b c>;
$c = 0;
cast @a, $wiz;
is $c, 0, 'len: cast on array doesn\'t trigger magic';
$c = 0;
$d = undef;
my $b = scalar @a;
is $c, 1, 'len: get array length triggers magic correctly';
is $d, 3, 'len: get array length have correct default length';
is $b, $n, 'len: get array length correctly';
$c = 0;
$d = undef;
$b = $#a;
is $c, 1, 'len: get last array index triggers magic correctly';
is $d, 3, 'len: get last array index have correct default length';
is $b, $n - 1, 'len: get last array index correctly';
$n = 0;
$c = 0;
$d = undef;
$b = scalar @a;
is $c, 1, 'len: get array length 0 triggers magic correctly';
is $d, 3, 'len: get array length 0 have correct default length';
is $b, 0, 'len: get array length 0 correctly';
$n = undef;
@a = ();
cast @a, $wiz;
$c = 0;
$d = undef;
$b = scalar @a;
is $c, 1, 'len: get empty array length triggers magic correctly';
is $d, 0, 'len: get empty array length have correct default length';
is $b, 0, 'len: get empty array length correctly';
$c = 0;
$d = undef;
$b = $#a;
is $c, 1, 'len: get last empty array index triggers magic correctly';
is $d, 0, 'len: get last empty array index have correct default length';
is $b, -1, 'len: get last empty array index correctly';
SKIP: {
skip 'len magic is no longer called for scalars' => 16 + 6
if VMG_COMPAT_SCALAR_NOLEN;
SKIP: {
skip 'length() no longer calls len magic on plain scalars' => 16
if VMG_COMPAT_SCALAR_LENGTH_NOLEN;
$c = 0;
$n = 1 + int rand 1000;
# length magic on scalars needs also get magic to be triggered.
my $wiz = wizard get => sub { return 'anything' },
len => sub { $d = $_[2]; ++$c; return $n };
my $x = 6789;
$c = 0;
cast $x, $wiz;
is $c, 0, 'len: cast on scalar doesn\'t trigger magic';
$c = 0;
$d = undef;
$b = length $x;
is $c, 1, 'len: get scalar length triggers magic correctly';
is $d, 4, 'len: get scalar length have correct default length';
is $b, $n, 'len: get scalar length correctly';
$n = 0;
$c = 0;
$d = undef;
$b = length $x;
is $c, 1, 'len: get scalar length 0 triggers magic correctly';
is $d, 4, 'len: get scalar length 0 have correct default length';
is $b, $n, 'len: get scalar length 0 correctly';
$n = undef;
$x = '';
cast $x, $wiz;
$c = 0;
$d = undef;
$b = length $x;
is $c, 1, 'len: get empty scalar length triggers magic correctly';
is $d, 0, 'len: get empty scalar length have correct default length';
is $b, 0, 'len: get empty scalar length correctly';
$x = "\x{20AB}ongs";
cast $x, $wiz;
{
use bytes;
$c = 0;
$d = undef;
$b = length $x;
is $c, 1, 'len: get utf8 scalar length in bytes triggers magic correctly';
is $d, 7, 'len: get utf8 scalar length in bytes have correct default length';
is $b, $d,'len: get utf8 scalar length in bytes correctly';
}
$c = 0;
$d = undef;
$b = length $x;
is $c, 1, 'len: get utf8 scalar length triggers magic correctly';
is $d, 5, 'len: get utf8 scalar length have correct default length';
is $b, $d, 'len: get utf8 scalar length correctly';
}
{
our $c;
# length magic on scalars needs also get magic to be triggered.
my $wiz = wizard get => sub { 0 },
len => sub { $d = $_[2]; ++$c; return $_[2] };
{
my $x = "banana";
cast $x, $wiz;
local $c = 0;
pos($x) = 2;
is $c, 1, 'len: pos scalar triggers magic correctly';
is $d, 6, 'len: pos scalar have correct default length';
is $x, 'banana', 'len: pos scalar works correctly'
}
{
my $x = "hl\x{20AB}gh"; # Force utf8 on string
cast $x, $wiz;
local $c = 0;
substr($x, 2, 1) = 'a';
is $c, 1, 'len: substr utf8 scalar triggers magic correctly';
is $d, 5, 'len: substr utf8 scalar have correct default length';
is $x, 'hlagh', 'len: substr utf8 scalar correctly';
}
}
}
SKIP: {
skip 'len magic is no longer called for negative array indices' => 5
if "$]" >= 5.025_004;
my @val = (4 .. 6);
my $wv = init_value @val, 'len', 'len';
value { $val[-1] = 8 } [ 4, 5, 6 ];
dispell @val, $wv;
is_deeply \@val, [ 4, 5, 8 ], 'len: after value';
}
{
local $@;
my $wua = eval { wizard len => \undef };
is $@, '', 'len: noop wizard (for arrays) creation does not croak';
my @a = ('a' .. 'z');
eval { cast @a, $wua };
is $@, '', 'len: noop wizard (for arrays) cast does not croak';
my $l;
eval { $l = $#a };
is $@, '', 'len: noop wizard (for arrays) invocation does not croak';
is $l, 25, 'len: noop magic on an array returns the previous length';
my $wus = eval { wizard get => \undef, len => \undef };
is $@, '', 'len: noop wizard (for strings) creation does not croak';
for ([ 'euro', 'string' ], [ "\x{20AC}uro", 'unicode string' ]) {
my ($euro, $desc) = @$_;
eval { cast $euro, $wus };
is $@, '', 'len: noop wizard (for strings) cast does not croak';
eval { pos($euro) = 2 };
is $@, '', 'len: noop wizard (for strings) invocation does not croak';
my ($rest) = ($euro =~ /(.*)/g);
is $rest, 'ro', "len: noop magic on a $desc returns the previous length";
}
}
|