blob: 5244a85e3ab29d37d4c1fdf5ead0ba36b61b5734 [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
use strict;
use warnings;
package MyHash;
use base qw( Lucy::Object::Hash );
sub oodle { }
package RAMFolderOfDeath;
use base qw( Lucy::Store::RAMFolder );
sub open_in {
my ( $self, $filename ) = @_;
die "Sweet, sweet death.";
}
package OnceRemoved;
use base qw( Lucy::Object::Obj );
our $serialize_was_called = 0;
sub serialize {
my ( $self, $outstream ) = @_;
$serialize_was_called++;
$self->SUPER::serialize($outstream);
}
package TwiceRemoved;
use base qw( OnceRemoved );
package main;
use Lucy::Test;
use Test::More tests => 9;
use Storable qw( nfreeze );
{
my $twice_removed = TwiceRemoved->new;
# This triggers a call to Obj_Serialize() via the VTable dispatch.
my $frozen = nfreeze($twice_removed);
ok( $serialize_was_called,
"Overridden method in intermediate class recognized" );
my $vtable = $twice_removed->get_vtable;
is( $vtable->get_name, "TwiceRemoved", "correct class" );
my $parent_vtable = $vtable->get_parent;
is( $parent_vtable->get_name, "OnceRemoved", "correct parent class" )
}
my $stringified;
my $storage = Lucy::Object::Hash->new;
{
my $subclassed_hash = MyHash->new;
$stringified = $subclassed_hash->to_string;
isa_ok( $subclassed_hash, "MyHash", "Perl isa reports correct subclass" );
# Store the subclassed object. At the end of this block, the Perl object
# will go out of scope and DESTROY will be called, but the Clownfish object
# will persist.
$storage->store( "test", $subclassed_hash );
}
my $resurrected = $storage->_fetch("test");
isa_ok( $resurrected, "MyHash", "subclass name survived Perl destruction" );
is( $resurrected->to_string, $stringified,
"It's the same Hash from earlier (though a different Perl object)" );
my $booga = Lucy::Object::CharBuf->new("booga");
$resurrected->store( "ooga", $booga );
is( $resurrected->fetch("ooga"),
"booga", "subclassed object still performs correctly at the C level" );
my $methods = Lucy::Object::VTable->novel_host_methods('MyHash');
is_deeply( $methods->to_perl, ['oodle'], "novel_host_methods" );
my $folder = RAMFolderOfDeath->new;
eval { $folder->slurp_file('foo') }; # calls open_in, which dies per above.
like( $@, qr/sweet/i, "override vtable method with pure perl method" );