Alien-Xrepo

 view release on metacpan or  search on metacpan

t/052_runtime.t  view on Meta::CPAN

use v5.40;
use blib;
use Test2::V0 '!subtest', -no_srand => 1;
use Test2::Util::Importer 'Test2::Tools::Subtest' => ( subtest_streamed => { -as => 'subtest' } );
use File::Temp qw[tempdir];
use JSON::PP   qw[encode_json];
use Path::Tiny;
use Config;
use Alien::Xrepo;
use Alien::Xrepo::Runtime;
use Alien::Xrepo::Build::Recipe;
use experimental 'class';

# A spy engine whose fetch serves canned PackageInfo and counts calls, so the
# laziness/caching of the runtime layer can be verified without xrepo.
class Alien::Xrepo::Runtime::TestSpy {
    field $calls : reader = 0;

    method fetch ( $name, $version, %opts ) {
        $calls++;
        return Alien::Xrepo::PackageInfo->new(
            includedirs => ["C:/store/$name/include"],
            libfiles    => ["C:/store/$name/bin/$name.dll"],
            license     => undef,
            linkdirs    => ["C:/store/$name/lib"],
            links       => [$name],
            shared      => 1,
            static      => 0,
            version     => $version // '9.9.9',
            libpath     => "C:/store/$name/bin/$name.dll",
            bindirs     => ["C:/store/$name/bin"],
            installdir  => "C:/store/$name",
            kind        => 'library'
        );
    }
}

class Alien::Xrepo::Runtime::TestDyn : isa(Alien::Xrepo::Runtime) {
    method pkg_name {'zstd'}
}

# A spy that records the opts each fetch was called with, so recipe defaults
# flowing into dynamic resolution can be checked.
class Alien::Xrepo::Runtime::TestOpts : isa(Alien::Xrepo::Runtime::TestSpy) {
    field $seen = [];
    method seen {$seen}

    method fetch ( $name, $version, %opts ) {
        push @$seen, { name => $name, opts => {%opts} };
        $self->SUPER::fetch( $name, $version, %opts );
    }
}

# The single-source pattern: the whole dist description (name, packages,
# defaults, local_repos) lives in one subclass method.
class Alien::Xrepo::Runtime::TestFull : isa(Alien::Xrepo::Runtime) {

    method recipe {
        return {
            name        => 'Alien-TestFull',
            packages    => [ { name => 'zstd', version => '1.5.6', kind => 'shared' }, 'libsdl3' ],
            defaults    => { mode => 'release' },
            local_repos => ['vendor/recipes'],
        };
    }
}

# Declares both; recipe() must win.
class Alien::Xrepo::Runtime::TestBoth : isa(Alien::Xrepo::Runtime) {
    method recipe   { return { packages => ['zstd'] }; }
    method pkg_name {'libsdl3'}
}
my $dir = tempdir( CLEANUP => 1 );
subtest 'dynamic mode: subclass declares pkg_name, fetch is lazy and cached' => sub {
    my $spy = Alien::Xrepo::Runtime::TestSpy->new;
    my $a   = Alien::Xrepo::Runtime::TestDyn->new( repo => $spy );
    is [ $a->package_names ], ['zstd'],                  'pkg_name fallback read from subclass method';
    is $a->version,           '9.9.9',                   'version defaults to store';
    is $a->cflags,            '-IC:/store/zstd/include', 'cflags from includedirs';
    like $a->libs,    qr/-LC:.*\/zstd\/lib/, 'libs from linkdirs/links';
    like $a->libpath, qr/zstd\.dll/,         'libpath is the runtime library';
    is scalar @{ [ $a->bin_dir ] }, 1, 'bin_dir list';
    like $a->dist_dir, qr/zstd/, 'dist_dir is the install root';
    is $a->install_type, 'share', 'a fetchable package is a share install';
    is $spy->calls,      1,       'all accessors shared one fetch';
    $a->cflags;
    $a->libs;
    is $spy->calls, 1, 'second access is cached';
};
subtest 'per-package defs and install_opts reach the fetch' => sub {
    my $spy = Alien::Xrepo::Runtime::TestSpy->new;
    my $a   = Alien::Xrepo::Runtime->new(
        pkg_name     => [ { name => 'zstd', version => '1.5.6', kind => 'shared', configs => { legacy => 1 } } ],
        install_opts => { mode => 'release' },
        repo         => $spy,
    );
    $a->version;
    is $spy->calls, 1,       'one fetch happened';
    is $a->version, '1.5.6', 'per-package version honored';
};
subtest 'multi-package alt() pins accessors to a package' => sub {
    my $spy = Alien::Xrepo::Runtime::TestSpy->new;
    my $a   = Alien::Xrepo::Runtime->new( pkg_name => [ 'zstd', 'libsdl3' ], repo => $spy );
    my $alt = $a->alt('libsdl3');
    like $alt->cflags, qr/libsdl3/, 'alt accessors pinned to libsdl3';
    like $a->cflags,   qr/zstd/,    'primary accessors stay on zstd';
    ok $a->alt eq $a, 'alt of the primary returns self';
    like dies { $a->alt('nope') }, qr/Unknown package/, 'alt of an unknown package dies';
};
subtest 'bin_dir / prepend_to_path put a shipped tool on PATH' => sub {



( run in 2.095 seconds using v1.01-cache-2.11-cpan-54e63673c56 )