blob: 83dec4068bd328ea7744d33cbebc7b7dc5c82d61 [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;
use Test::More tests => 30;
BEGIN { use_ok('Clownfish::Method') }
use Clownfish::Parser;
my $parser = Clownfish::Parser->new;
$parser->parcel_definition('parcel Neato;')
or die "failed to process parcel_definition";
my %args = (
parcel => 'Neato',
return_type => $parser->type('Obj*'),
class_name => 'Neato::Foo',
class_cnick => 'Foo',
param_list => $parser->param_list('(Foo *self, int32_t count = 0)'),
macro_sym => 'Return_An_Obj',
);
my $method = Clownfish::Method->new(%args);
isa_ok( $method, "Clownfish::Method" );
ok( $method->parcel, "parcel exposure by default" );
eval { my $death = Clownfish::Method->new( %args, extra_arg => undef ) };
like( $@, qr/extra_arg/, "Extra arg kills constructor" );
eval { Clownfish::Method->new( %args, macro_sym => 'return_an_obj' ); };
like( $@, qr/macro_sym/, "Invalid macro_sym kills constructor" );
my $dupe = Clownfish::Method->new(%args);
ok( $method->compatible($dupe), "compatible()" );
my $macro_sym_differs = Clownfish::Method->new( %args, macro_sym => 'Eat' );
ok( !$method->compatible($macro_sym_differs),
"different macro_sym spoils compatible()"
);
ok( !$macro_sym_differs->compatible($method), "... reversed" );
my $extra_param = Clownfish::Method->new( %args,
param_list =>
$parser->param_list('(Foo *self, int32_t count = 0, int b)'), );
ok( !$method->compatible($macro_sym_differs),
"extra param spoils compatible()"
);
ok( !$extra_param->compatible($method), "... reversed" );
my $default_differs = Clownfish::Method->new( %args,
param_list => $parser->param_list('(Foo *self, int32_t count = 1)'), );
ok( !$method->compatible($default_differs),
"different initial_value spoils compatible()"
);
ok( !$default_differs->compatible($method), "... reversed" );
my $missing_default = Clownfish::Method->new( %args,
param_list => $parser->param_list('(Foo *self, int32_t count)'), );
ok( !$method->compatible($missing_default),
"missing initial_value spoils compatible()"
);
ok( !$missing_default->compatible($method), "... reversed" );
my $param_name_differs = Clownfish::Method->new( %args,
param_list => $parser->param_list('(Foo *self, int32_t countess)'), );
ok( !$method->compatible($param_name_differs),
"different param name spoils compatible()"
);
ok( !$param_name_differs->compatible($method), "... reversed" );
my $param_type_differs = Clownfish::Method->new( %args,
param_list => $parser->param_list('(Foo *self, uint32_t count)'), );
ok( !$method->compatible($param_type_differs),
"different param type spoils compatible()"
);
ok( !$param_type_differs->compatible($method), "... reversed" );
my $self_type_differs = Clownfish::Method->new(
%args,
class_name => 'Neato::Bar',
class_cnick => 'Bar',
param_list => $parser->param_list('(Bar *self, int32_t count = 0)'),
);
ok( $method->compatible($self_type_differs),
"different self type still compatible(), since can't test inheritance" );
ok( $self_type_differs->compatible($method), "... reversed" );
my $not_final = Clownfish::Method->new(%args);
my $final = $not_final->finalize;
eval { $method->override($final); };
like( $@, qr/final/i, "Can't override final method" );
ok( $not_final->compatible($final), "Finalize clones properly" );
for my $meth_meth (qw( short_method_sym full_method_sym full_offset_sym)) {
eval { my $blah = $method->$meth_meth; };
like( $@, qr/invoker/, "$meth_meth requires invoker" );
}
my %sub_args = ( class => 'Neato::Obj', cnick => 'Obj' );
isa_ok(
$parser->subroutine_declaration_statement( $_, 0, %sub_args )->{declared},
"Clownfish::Method",
"method declaration: $_"
)
for (
'public int Do_Foo(Obj *self);',
'parcel Obj* Gimme_An_Obj(Obj *self);',
'void Do_Whatever(Obj *self, uint32_t a_num, float real);',
'private Foo* Fetch_Foo(Obj *self, int num);',
);
ok( $parser->subroutine_declaration_statement( $_, 0, %sub_args )->{declared}
->final,
"final method: $_"
) for ( 'public final void The_End(Obj *self);', );