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 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
|
#!/usr/bin/env perl
BEGIN { require './t/inc/setup.pl' };
use strict;
use warnings;
use Scalar::Util;
plan skip_all => 'Need gobject-introspection 1.35.5'
unless check_gi_version (1, 35, 5);
plan tests => 68;
my @packages = qw/WeakNonFloater WeakFloater StrongNonFloater StrongFloater/;
my %package_to_subclass = (
WeakNonFloater => 'NonFloatingObjectSubclass',
WeakFloater => 'FloatingObjectSubclass',
StrongNonFloater => 'NonFloatingObjectSubclass',
StrongFloater => 'FloatingObjectSubclass',
);
my %package_to_warner = (
WeakNonFloater => sub { die $_[0] if -1 == index $_[0], 'Asked to hand out object' },
WeakFloater => sub { die $_[0] if -1 == index $_[0], 'Asked to hand out object' },
StrongNonFloater => sub { die $_[0] },
StrongFloater => sub { die $_[0] },
);
my %package_to_ref_count_offset = (
WeakNonFloater => 0,
WeakFloater => 0,
StrongNonFloater => 1,
StrongFloater => 1,
);
my %package_to_ref_gone = (
WeakNonFloater => Glib::TRUE,
WeakFloater => Glib::TRUE,
StrongNonFloater => Glib::FALSE,
StrongFloater => Glib::FALSE,
);
my %package_to_floating = (
WeakNonFloater => Glib::FALSE,
WeakFloater => Glib::TRUE,
StrongNonFloater => Glib::FALSE,
StrongFloater => Glib::TRUE,
);
# Test that the invocant is not leaked.
foreach my $package (@packages) {
{
my $nf = $package->new;
$nf->get_ref_info_for_vfunc_return_object_transfer_full;
Scalar::Util::weaken ($nf);
is ($nf, undef, "no leak for $package");
}
}
# Test transfer-none&return/out semantics.
foreach my $package (@packages) {
local $SIG{__WARN__} = $package_to_warner{$package};
foreach my $method (qw/get_ref_info_for_vfunc_return_object_transfer_none
get_ref_info_for_vfunc_out_object_transfer_none/)
{
my $nf = $package->new;
my ($ref_count, $is_floating) = $nf->$method;
is ($ref_count, 1, "transfer-none&return/out: ref count for $package");
ok (!$is_floating, "transfer-none&return/out: floating for $package");
}
}
# Test transfer-full&return/out semantics.
foreach my $package (@packages) {
foreach my $method (qw/get_ref_info_for_vfunc_return_object_transfer_full
get_ref_info_for_vfunc_out_object_transfer_full/)
{
my $nf = $package->new;
my ($ref_count, $is_floating) = $nf->$method;
is ($ref_count, 1 + $package_to_ref_count_offset{$package},
"transfer-full&return/out: ref count for $package");
ok (!$is_floating, "transfer-full&return/out: floating for $package");
is ($nf->is_ref_gone, $package_to_ref_gone{$package},
"transfer-full&return/out: ref gone for $package");
}
}
# Test transfer-none&in semantics.
foreach my $package (@packages) {
{
my $nf = $package->new;
my ($ref_count, $is_floating) =
$nf->get_ref_info_for_vfunc_in_object_transfer_none ($package_to_subclass{$package});
TODO: {
local $TODO = $package =~ /^Weak/
? 'ref count test unreliable due to unpredictable behavior of perl-Glib'
: undef;
is ($ref_count, 1 + $package_to_ref_count_offset{$package},
"transfer-none&in: ref count for $package");
}
is ($is_floating, $package_to_floating{$package},
"transfer-none&in: floating for $package");
is ($nf->is_ref_gone, $package_to_ref_gone{$package},
"transfer-none&in: ref gone for $package");
}
}
# Test transfer-full&in semantics.
foreach my $package (@packages) {
{
my $nf = $package->new;
my ($ref_count, $is_floating) =
$nf->get_ref_info_for_vfunc_in_object_transfer_full ($package_to_subclass{$package});
TODO: {
local $TODO = $package =~ /^Weak/
? 'ref count test unreliable due to unpredictable behavior of perl-Glib'
: undef;
is ($ref_count, 0 + $package_to_ref_count_offset{$package},
"transfer-full&in: ref count for $package");
}
ok (!$is_floating, "transfer-full&in: floating for $package");
is ($nf->is_ref_gone, $package_to_ref_gone{$package},
"transfer-full&in: ref gone for $package");
}
}
# --------------------------------------------------------------------------- #
{
package NonFloatingObjectSubclass;
use Glib::Object::Subclass 'Glib::Object';
}
{
package FloatingObjectSubclass;
use Glib::Object::Subclass 'Glib::InitiallyUnowned';
}
{
package Base;
use Glib::Object::Subclass 'GI::Object';
sub VFUNC_RETURN_OBJECT_TRANSFER_NONE {
my ($self) = @_;
my $o = $self->_create;
$self->_store ($o);
return $o;
}
sub VFUNC_RETURN_OBJECT_TRANSFER_FULL {
my ($self) = @_;
my $o = $self->_create;
$self->_store ($o);
return $o;
}
sub VFUNC_OUT_OBJECT_TRANSFER_NONE {
my ($self) = @_;
my $o = $self->_create;
$self->_store ($o);
return $o;
}
sub VFUNC_OUT_OBJECT_TRANSFER_FULL {
my ($self) = @_;
my $o = $self->_create;
$self->_store ($o);
return $o;
}
sub VFUNC_IN_OBJECT_TRANSFER_NONE {
my ($self, $o) = @_;
$self->_store ($o);
}
sub VFUNC_IN_OBJECT_TRANSFER_FULL {
my ($self, $o) = @_;
$self->_store ($o);
}
sub is_ref_gone {
my ($self) = @_;
not defined $self->_retrieve;
}
}
{
package WeakNonFloater;
use Glib::Object::Subclass 'Base';
sub _create {
NonFloatingObjectSubclass->new;
}
sub _store {
my ($self, $o) = @_;
Scalar::Util::weaken ($self->{_ref} = $o);
}
sub _retrieve {
my ($self) = @_;
$self->{_ref};
}
}
{
package WeakFloater;
use Glib::Object::Subclass 'Base';
sub _create {
FloatingObjectSubclass->new;
}
sub _store {
my ($self, $o) = @_;
Scalar::Util::weaken ($self->{_ref} = $o);
}
sub _retrieve {
my ($self) = @_;
$self->{_ref};
}
}
{
package StrongNonFloater;
use Glib::Object::Subclass 'Base';
sub _create {
NonFloatingObjectSubclass->new;
}
sub _store {
my ($self, $o) = @_;
$self->{_ref} = $o;
}
sub _retrieve {
my ($self) = @_;
$self->{_ref};
}
}
{
package StrongFloater;
use Glib::Object::Subclass 'Base';
sub _create {
FloatingObjectSubclass->new;
}
sub _store {
my ($self, $o) = @_;
$self->{_ref} = $o;
}
sub _retrieve {
my ($self) = @_;
$self->{_ref};
}
}
|