Affix
view release on metacpan or search on metacpan
t/025_affix_wrap.t view on Meta::CPAN
if ( $arg0->type->isa('Affix::Wrap::Type::CodeRef') ) {
is( $arg0->type->ret->affix_type, 'Void', 'Callback returns Void' );
is( $arg0->type->params->[0]->affix_type, 'Int', 'Callback takes Int' );
is( $arg0->type->affix_type, 'Callback[[Int] => Void]', 'Signature matches' );
}
};
subtest 'Complex Types' => sub {
my $dir = Path::Tiny->tempdir;
spew_files(
$dir,
'edge.h' => <<'EOF',
typedef struct {
int data[16];
char* name;
float matrix[4][4];
} Buffer;
typedef const char * const * double_ptr;
typedef int *array_of_pointers[5];
EOF
'main.c' => '#include "edge.h"'
);
my $parser = $driver_class->new( project_files => [ $dir->child('edge.h')->stringify ] );
my @objs = $parser->parse( $dir->child('main.c')->stringify, [ $dir->stringify ] );
my ($buf_td) = grep { $_->name eq 'Buffer' } @objs;
ok $buf_td, 'Found Buffer Typedef';
my $buf = $buf_td->underlying;
if ($buf) {
my $m0 = $buf->members->[0]; # int data[16]
isa_ok( $m0->type, ['Affix::Wrap::Type::Array'], 'Member 0 is Array' );
is( $m0->type->count, 16, 'Array count 16' );
is( $m0->type->affix_type, 'Array[Int, 16]', 'Affix Sig: Array[Int, 16]' );
my $m1 = $buf->members->[1]; # char* name
isa_ok( $m1->type, ['Affix::Wrap::Type::Pointer'], 'Member 1 is Pointer' );
is( $m1->type->affix_type, 'Pointer[Char]', 'Affix Sig: Pointer[Char]' );
my $m2 = $buf->members->[2]; # float matrix[4][4]
isa_ok( $m2->type, ['Affix::Wrap::Type::Array'], 'Member 2 is Array' );
is( $m2->type->affix_type, 'Array[Array[Float, 4], 4]', '2D Array Affix Sig' );
}
my ($dp) = grep { $_->name eq 'double_ptr' } @objs;
ok( $dp, 'Found double_ptr' );
is( $dp->underlying->affix_type, 'Pointer[Pointer[Char]]', 'double_ptr affix_type' );
my ($ap) = grep { $_->name eq 'array_of_pointers' } @objs;
ok( $ap, 'Found array_of_pointers' );
is( $ap->underlying->affix_type, 'Array[Pointer[Int], 5]', 'array_of_pointers affix_type' );
};
subtest 'Compile -> Bind -> Affix' => sub {
use v5.40;
use Affix;
use Affix::Build;
use Affix::Wrap;
#
my $src = <<~'';
//ext: .c
int return_six() { return 6; }
my $dir = Path::Tiny->tempdir;
spew_files( $dir, 'main.c' => $src );
my $lib = compile_ok($src);
my $pkg = $driver_class eq 'Affix::Wrap::Driver::Clang' ? 'Testing_clang' : 'Testing_regex';
#
my $binder = Affix::Wrap->new(
driver => $driver_class->new( project_files => [ $dir->child('main.c')->stringify ] ),
include_dirs => [ './t/src', 'src', 'C:\Users\S\Documents\GitHub\Affix.pm\t\src' ]
);
$binder->wrap( $lib, $pkg );
#
is $pkg->can('return_six')->(), 6, 'returned 6';
};
subtest 'Static Generation' => sub {
my $dir = Path::Tiny->tempdir;
spew_files(
$dir,
'static.h' => <<'EOF',
#define STATIC_VAL 42
typedef struct { int x; } StaticStruct;
int static_func(int i);
EOF
'main.c' => '#include "static.h"'
);
my $parser = $driver_class->new( project_files => [ $dir->child('static.h')->stringify ] );
my $binder = Affix::Wrap->new( driver => $parser );
my $pm_file = $dir->child('StaticLib.pm');
$binder->generate( 'dummy_lib', 'StaticLib', $pm_file->stringify );
ok -e $pm_file, 'Generated .pm file';
my $content = $pm_file->slurp_utf8;
like $content, qr/package\s+StaticLib\s*{/, 'Package decl';
like $content, qr/use constant STATIC_VAL => 42;/, 'Constant generated';
like $content, qr/typedef 'StaticStruct' => Struct\[ x => Int \];/, 'Struct typedef generated';
like $content, qr/affix \$lib, ('static_func'|\[_static_func => 'static_func'\]) => \[Int\], Int;/, 'Function affix generated';
# Syntax check
my ( undef, undef, $exit ) = capture { system $^X, '-Ilib', '-c', $pm_file->stringify };
is $exit >> 8, 0, 'Generated code syntax check OK';
};
};
}
run_tests_for_driver( 'Affix::Wrap::Driver::Clang', 'Clang System' ) if $CLANG_AVAIL;
run_tests_for_driver( 'Affix::Wrap::Driver::Regex', 'Regex System (Fallback)' );
done_testing();
( run in 0.924 second using v1.01-cache-2.11-cpan-2398b32b56e )