Mini Shell
.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings. \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
. ds -- \(*W-
. ds PI pi
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds -- \|\(em\|
. ds PI \(*p
. ds L" ``
. ds R" ''
. ds C`
. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
. if \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{\
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\" ========================================================================
.\"
.IX Title "Test::Alien 3"
.TH Test::Alien 3 "2024-10-29" "perl v5.32.1" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
Test::Alien \- Testing tools for Alien modules
.SH "VERSION"
.IX Header "VERSION"
version 2.84
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
Test commands that come with your Alien:
.PP
.Vb 3
\& use Test2::V0;
\& use Test::Alien;
\& use Alien::patch;
\&
\& alien_ok \*(AqAlien::patch\*(Aq;
\& run_ok([ \*(Aqpatch\*(Aq, \*(Aq\-\-version\*(Aq ])
\& \->success
\& # we only accept the version written
\& # by Larry ...
\& \->out_like(qr{Larry Wall});
\&
\& done_testing;
.Ve
.PP
Test that your library works with \f(CW\*(C`XS\*(C'\fR:
.PP
.Vb 3
\& use Test2::V0;
\& use Test::Alien;
\& use Alien::Editline;
\&
\& alien_ok \*(AqAlien::Editline\*(Aq;
\& my $xs = do { local $/; <DATA> };
\& xs_ok $xs, with_subtest {
\& my($module) = @_;
\& ok $module\->version;
\& };
\&
\& done_testing;
\&
\& _\|_DATA_\|_
\&
\& #include "EXTERN.h"
\& #include "perl.h"
\& #include "XSUB.h"
\& #include <editline/readline.h>
\&
\& const char *
\& version(const char *class)
\& {
\& return rl_library_version;
\& }
\&
\& MODULE = TA_MODULE PACKAGE = TA_MODULE
\&
\& const char *version(class);
\& const char *class;
.Ve
.PP
Test that your library works with FFI::Platypus:
.PP
.Vb 3
\& use Test2::V0;
\& use Test::Alien;
\& use Alien::LibYAML;
\&
\& alien_ok \*(AqAlien::LibYAML\*(Aq;
\& ffi_ok { symbols => [\*(Aqyaml_get_version\*(Aq] }, with_subtest {
\& my($ffi) = @_;
\& my $get_version = $ffi\->function(yaml_get_version => [\*(Aqint*\*(Aq,\*(Aqint*\*(Aq,\*(Aqint*\*(Aq] => \*(Aqvoid\*(Aq);
\& $get_version\->call(\emy $major, \emy $minor, \emy $patch);
\& like $major, qr{[0\-9]+};
\& like $minor, qr{[0\-9]+};
\& like $patch, qr{[0\-9]+};
\& };
\&
\& done_testing;
.Ve
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
This module provides tools for testing Alien modules. It has hooks
to work easily with Alien::Base based modules, but can also be used
via the synthetic interface to test non Alien::Base based Alien
modules. It has very modest prerequisites.
.PP
Prior to this module the best way to test a Alien module was via Test::CChecker.
The main downside to that module is that it is heavily influenced by and uses
ExtUtils::CChecker, which is a tool for checking at install time various things
about your compiler. It was also written before Alien::Base became as stable as it
is today. In particular, Test::CChecker does its testing by creating an executable
and running it. Unfortunately Perl uses extensions by creating dynamic libraries
and linking them into the Perl process, which is different in subtle and error prone
ways. This module attempts to test the libraries in the way that they will actually
be used, via either \f(CW\*(C`XS\*(C'\fR or FFI::Platypus. It also provides a mechanism for
testing binaries that are provided by the various Alien modules (for example
Alien::gmake and Alien::patch).
.PP
Alien modules can actually be usable without a compiler, or without FFI::Platypus
(for example, if the library is provided by the system, and you are using FFI::Platypus,
or if you are building from source and you are using \f(CW\*(C`XS\*(C'\fR), so tests with missing
prerequisites are automatically skipped. For example, \*(L"xs_ok\*(R" will automatically skip
itself if a compiler is not found, and \*(L"ffi_ok\*(R" will automatically skip itself
if FFI::Platypus is not installed.
.SH "FUNCTIONS"
.IX Header "FUNCTIONS"
.SS "alien_ok"
.IX Subsection "alien_ok"
.Vb 2
\& alien_ok $alien, $message;
\& alien_ok $alien;
.Ve
.PP
Load the given Alien instance or class. Checks that the instance or class conforms to the same
interface as Alien::Base. Will be used by subsequent tests. The \f(CW$alien\fR module only needs to
provide these methods in order to conform to the Alien::Base interface:
.IP "cflags" 4
.IX Item "cflags"
String containing the compiler flags
.IP "libs" 4
.IX Item "libs"
String containing the linker and library flags
.IP "dynamic_libs" 4
.IX Item "dynamic_libs"
List of dynamic libraries. Returns empty list if the Alien module does not provide this.
.IP "bin_dir" 4
.IX Item "bin_dir"
Directory containing tool binaries. Returns empty list if the Alien module does not provide
this.
.PP
If your Alien module does not conform to this interface then you can create a synthetic Alien
module using the \*(L"synthetic\*(R" function.
.SS "synthetic"
.IX Subsection "synthetic"
.Vb 1
\& my $alien = synthetic \e%config;
.Ve
.PP
Create a synthetic Alien module which can be passed into \*(L"alien_ok\*(R". \f(CW\*(C`\e%config\*(C'\fR
can contain these keys (all of which are optional):
.IP "cflags" 4
.IX Item "cflags"
String containing the compiler flags.
.IP "cflags_static" 4
.IX Item "cflags_static"
String containing the static compiler flags (optional).
.IP "libs" 4
.IX Item "libs"
String containing the linker and library flags.
.IP "libs_static" 4
.IX Item "libs_static"
String containing the static linker flags (optional).
.IP "dynamic_libs" 4
.IX Item "dynamic_libs"
List reference containing the dynamic libraries.
.IP "bin_dir" 4
.IX Item "bin_dir"
Tool binary directory.
.IP "runtime_prop" 4
.IX Item "runtime_prop"
Runtime properties.
.PP
See Test::Alien::Synthetic for more details.
.SS "run_ok"
.IX Subsection "run_ok"
.Vb 2
\& my $run = run_ok $command;
\& my $run = run_ok $command, $message;
.Ve
.PP
Runs the given command, falling back on any \f(CW\*(C`Alien::Base#bin_dir\*(C'\fR methods provided by Alien modules
specified with \*(L"alien_ok\*(R".
.PP
\&\f(CW$command\fR can be either a string or an array reference.
.PP
Only fails if the command cannot be found, or if it is killed by a signal! Returns a Test::Alien::Run
object, which you can use to test the exit status, output and standard error.
.PP
Always returns an instance of Test::Alien::Run, even if the command could not be found.
.SS "xs_ok"
.IX Subsection "xs_ok"
.Vb 2
\& xs_ok $xs;
\& xs_ok $xs, $message;
.Ve
.PP
Compiles, links the given \f(CW\*(C`XS\*(C'\fR code and attaches to Perl.
.PP
If you use the special module name \f(CW\*(C`TA_MODULE\*(C'\fR in your \f(CW\*(C`XS\*(C'\fR
code, it will be replaced by an automatically generated
package name. This can be useful if you want to pass the same
\&\f(CW\*(C`XS\*(C'\fR code to multiple calls to \f(CW\*(C`xs_ok\*(C'\fR without subsequent
calls replacing previous ones.
.PP
\&\f(CW$xs\fR may be either a string containing the \f(CW\*(C`XS\*(C'\fR code,
or a hash reference with these keys:
.IP "xs" 4
.IX Item "xs"
The \s-1XS\s0 code. This is the only required element.
.IP "pxs" 4
.IX Item "pxs"
Extra ExtUtils::ParseXS arguments passed in as a hash reference.
.IP "cbuilder_check" 4
.IX Item "cbuilder_check"
The compile check that should be done prior to attempting to build.
Should be one of \f(CW\*(C`have_compiler\*(C'\fR or \f(CW\*(C`have_cplusplus\*(C'\fR. Defaults
to \f(CW\*(C`have_compiler\*(C'\fR.
.IP "cbuilder_config" 4
.IX Item "cbuilder_config"
Hash to override values normally provided by \f(CW\*(C`Config\*(C'\fR.
.IP "cbuilder_compile" 4
.IX Item "cbuilder_compile"
Extra The ExtUtils::CBuilder arguments passed in as a hash reference.
.IP "cbuilder_link" 4
.IX Item "cbuilder_link"
Extra The ExtUtils::CBuilder arguments passed in as a hash reference.
.IP "verbose" 4
.IX Item "verbose"
Spew copious debug information via test note.
.PP
You can use the \f(CW\*(C`with_subtest\*(C'\fR keyword to conditionally
run a subtest if the \f(CW\*(C`xs_ok\*(C'\fR call succeeds. If \f(CW\*(C`xs_ok\*(C'\fR
does not work, then the subtest will automatically be
skipped. Example:
.PP
.Vb 5
\& xs_ok $xs, with_subtest {
\& # skipped if $xs fails for some reason
\& my($module) = @_;
\& is $module\->foo, 1;
\& };
.Ve
.PP
The module name detected during the \s-1XS\s0 parsing phase will
be passed in to the subtest. This is helpful when you are
using a generated module name.
.PP
If you need to test \s-1XS \*(C+\s0 interfaces, see Test::Alien::CPP.
.PP
Caveats: \f(CW\*(C`xs_ok\*(C'\fR uses ExtUtils::ParseXS, which may call \f(CW\*(C`exit\*(C'\fR
under certain error conditions. While this is not really good
thing to happen in the middle of a test, it usually indicates
a real failure condition, and it should return a failure condition
so the test should still fail overall.
.PP
[version 2.53]
.PP
As of version 2.53, \f(CW\*(C`xs_ok\*(C'\fR will only remove temporary generated files
if the test is successful by default. You can force either always
or never removing the temporary generated files using the
\&\f(CW\*(C`TEST_ALIEN_ALWAYS_KEEP\*(C'\fR environment variable (see \*(L"\s-1ENVIRONMENT\*(R"\s0 below).
.SS "ffi_ok"
.IX Subsection "ffi_ok"
.Vb 3
\& ffi_ok;
\& ffi_ok \e%opt;
\& ffi_ok \e%opt, $message;
.Ve
.PP
Test that FFI::Platypus works.
.PP
\&\f(CW\*(C`\e%opt\*(C'\fR is a hash reference with these keys (all optional):
.IP "symbols" 4
.IX Item "symbols"
List references of symbols that must be found for the test to succeed.
.IP "ignore_not_found" 4
.IX Item "ignore_not_found"
Ignores symbols that aren't found. This affects functions accessed via
FFI::Platypus#attach and FFI::Platypus#function methods, and does
not influence the \f(CW\*(C`symbols\*(C'\fR key above.
.IP "lang" 4
.IX Item "lang"
Set the language. Used primarily for language specific native types.
.IP "api" 4
.IX Item "api"
Set the \s-1API.\s0 \f(CW\*(C`api = 1\*(C'\fR requires FFI::Platypus 0.99 or later. This
option was added with Test::Alien version 1.90, so your use line should
include this version as a safeguard to make sure it works:
.Sp
.Vb 3
\& use Test::Alien 1.90;
\& ...
\& ffi_ok ...;
.Ve
.PP
As with \*(L"xs_ok\*(R" above, you can use the \f(CW\*(C`with_subtest\*(C'\fR keyword to specify
a subtest to be run if \f(CW\*(C`ffi_ok\*(C'\fR succeeds (it will skip otherwise). The
FFI::Platypus instance is passed into the subtest as the first argument.
For example:
.PP
.Vb 4
\& ffi_ok with_subtest {
\& my($ffi) = @_;
\& is $ffi\->function(foo => [] => \*(Aqvoid\*(Aq)\->call, 42;
\& };
.Ve
.SS "helper_ok"
.IX Subsection "helper_ok"
.Vb 2
\& helper_ok $name;
\& helper_ok $name, $message;
.Ve
.PP
Tests that the given helper has been defined.
.SS "plugin_ok"
.IX Subsection "plugin_ok"
[version 2.52]
.PP
.Vb 2
\& plugin_ok $plugin_name, $message;
\& plugin_ok [$plugin_name, @args], $message;
.Ve
.PP
This applies an Alien::Build::Plugin to the interpolator used by \*(L"helper_ok\*(R", \*(L"interpolate_template_is\*(R"
and \*(L"interpolate_run_ok\*(R" so that you can test with any helpers that plugin provides. Useful,
for example for getting \f(CW\*(C`%{configure}\*(C'\fR from Alien::Build::Plugin::Build::Autoconf.
.SS "interpolate_template_is"
.IX Subsection "interpolate_template_is"
.Vb 4
\& interpolate_template_is $template, $string;
\& interpolate_template_is $template, $string, $message;
\& interpolate_template_is $template, $regex;
\& interpolate_template_is $template, $regex, $message;
.Ve
.PP
Tests that the given template when evaluated with the appropriate helpers will match
either the given string or regular expression.
.SS "interpolate_run_ok"
.IX Subsection "interpolate_run_ok"
[version 2.52]
.PP
.Vb 2
\& my $run = interpolate_run_ok $command;
\& my $run = interpolate_run_ok $command, $message;
.Ve
.PP
This is the same as \*(L"run_ok\*(R" except it runs the command through the interpolator first.
.SH "ENVIRONMENT"
.IX Header "ENVIRONMENT"
.ie n .IP """TEST_ALIEN_ALWAYS_KEEP""" 4
.el .IP "\f(CWTEST_ALIEN_ALWAYS_KEEP\fR" 4
.IX Item "TEST_ALIEN_ALWAYS_KEEP"
If this is defined then it will override the built in logic that decides if
the temporary files generated by \*(L"xs_ok\*(R" should be kept when the test file
terminates. If set to true the generated files will always be kept. If
set to false, then they will always be removed.
.ie n .IP """TEST_ALIEN_ALIENS_MISSING""" 4
.el .IP "\f(CWTEST_ALIEN_ALIENS_MISSING\fR" 4
.IX Item "TEST_ALIEN_ALIENS_MISSING"
By default, this module will warn you if some tools are used without first
invoking \*(L"alien_ok\*(R". This is usually a mistake, but if you really do
want to use one of these tools with no aliens loaded, you can set this
environment variable to false.
.SH "SEE ALSO"
.IX Header "SEE ALSO"
.IP "Alien" 4
.IX Item "Alien"
.PD 0
.IP "Alien::Base" 4
.IX Item "Alien::Base"
.IP "Alien::Build" 4
.IX Item "Alien::Build"
.IP "alienfile" 4
.IX Item "alienfile"
.IP "Test2" 4
.IX Item "Test2"
.IP "Test::Alien::Run" 4
.IX Item "Test::Alien::Run"
.IP "Test::Alien::CanCompile" 4
.IX Item "Test::Alien::CanCompile"
.IP "Test::Alien::CanPlatypus" 4
.IX Item "Test::Alien::CanPlatypus"
.IP "Test::Alien::Synthetic" 4
.IX Item "Test::Alien::Synthetic"
.IP "Test::Alien::CPP" 4
.IX Item "Test::Alien::CPP"
.PD
.SH "AUTHOR"
.IX Header "AUTHOR"
Author: Graham Ollis <plicease@cpan.org>
.PP
Contributors:
.PP
Diab Jerius (\s-1DJERIUS\s0)
.PP
Roy Storey (\s-1KIWIROY\s0)
.PP
Ilya Pavlov
.PP
David Mertens (run4flat)
.PP
Mark Nunberg (mordy, mnunberg)
.PP
Christian Walde (Mithaldu)
.PP
Brian Wightman (MidLifeXis)
.PP
Zaki Mughal (zmughal)
.PP
mohawk (mohawk2, \s-1ETJ\s0)
.PP
Vikas N Kumar (vikasnkumar)
.PP
Flavio Poletti (polettix)
.PP
Salvador Fandiño (salva)
.PP
Gianni Ceccarelli (dakkar)
.PP
Pavel Shaydo (zwon, trinitum)
.PP
Kang-min Liu (劉康民, gugod)
.PP
Nicholas Shipp (nshp)
.PP
Juan Julián Merelo Guervós (\s-1JJ\s0)
.PP
Joel Berger (\s-1JBERGER\s0)
.PP
Petr Písař (ppisar)
.PP
Lance Wicks (\s-1LANCEW\s0)
.PP
Ahmad Fatoum (a3f, \s-1ATHREEF\s0)
.PP
José Joaquín Atria (\s-1JJATRIA\s0)
.PP
Duke Leto (\s-1LETO\s0)
.PP
Shoichi Kaji (\s-1SKAJI\s0)
.PP
Shawn Laffan (\s-1SLAFFAN\s0)
.PP
Paul Evans (leonerd, \s-1PEVANS\s0)
.PP
Håkon Hægland (hakonhagland, \s-1HAKONH\s0)
.PP
nick nauwelaerts (\s-1INPHOBIA\s0)
.PP
Florian Weimer
.SH "COPYRIGHT AND LICENSE"
.IX Header "COPYRIGHT AND LICENSE"
This software is copyright (c) 2011\-2022 by Graham Ollis.
.PP
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
Zerion Mini Shell 1.0