App-karr
view release on metacpan or search on metacpan
t/30-foundation.t view on Meta::CPAN
my $cfg_dir = tempdir( CLEANUP => 1 );
my $cfg = $cfg_dir->child('config.yml');
$cfg->spew_utf8( "scan:\n - $parent\n" );
my $f = new_foundation( config => "$cfg" );
my @repos = $f->_discover_repos;
is scalar @repos, 1, 'only the repo with .karr found';
like "$repos[0]", qr/proj1/, 'correct repo discovered';
};
# ---------------------------------------------------------------------------
# Lock file
# ---------------------------------------------------------------------------
subtest 'no lock file â not held' => sub {
my $dir = tempdir( CLEANUP => 1 );
my $f = new_foundation();
ok ! $f->_lock_held( $dir ), 'no lock when file absent';
};
subtest 'stale lock (dead PID) â not held' => sub {
my $dir = tempdir( CLEANUP => 1 );
$dir->child('.karr.lock')->spew_utf8("999999999\n"); # unlikely PID
my $f = new_foundation();
ok ! $f->_lock_held( $dir ), 'stale lock treated as not held';
};
subtest 'live lock (our own PID) â held' => sub {
my $dir = tempdir( CLEANUP => 1 );
$dir->child('.karr.lock')->spew_utf8("$$\n"); # our PID
my $f = new_foundation();
ok $f->_lock_held( $dir ), 'own PID treated as held';
};
subtest 'acquire and release' => sub {
my $dir = tempdir( CLEANUP => 1 );
my $f = new_foundation();
$f->_acquire_lock( $dir );
my $pid = $dir->child('.karr.lock')->slurp_utf8;
chomp $pid;
is $pid, $$, 'lock file contains our PID';
$f->_release_lock( $dir );
ok ! $dir->child('.karr.lock')->exists, 'lock file removed';
};
# ---------------------------------------------------------------------------
# State file
# ---------------------------------------------------------------------------
subtest 'state get/set round-trip' => sub {
my $dir = tempdir( CLEANUP => 1 );
my $f = new_foundation();
is $f->_state_get( $dir, 'hash' ), undef, 'undef before any state written';
$f->_state_set( $dir, hash => 'abc123', last_exit => 0 );
is $f->_state_get( $dir, 'hash' ), 'abc123', 'hash persisted';
is $f->_state_get( $dir, 'last_exit' ), 0, 'last_exit persisted';
$f->_state_set( $dir, hash => 'def456' );
is $f->_state_get( $dir, 'hash' ), 'def456', 'hash updated';
is $f->_state_get( $dir, 'last_exit' ), 0, 'last_exit preserved on partial update';
};
# ---------------------------------------------------------------------------
# .karr file parsing
# ---------------------------------------------------------------------------
subtest '_load_karr: missing file â empty hash' => sub {
my $dir = tempdir( CLEANUP => 1 );
my $f = new_foundation();
my $k = $f->_load_karr( $dir );
is ref $k, 'HASH', 'returns hashref';
is scalar keys %$k, 0, 'empty when no .karr';
};
subtest '_load_karr: parses correctly' => sub {
my $dir = tempdir( CLEANUP => 1 );
write_karr_file( $dir, command => 'echo hello', max_runtime => 900 );
my $f = new_foundation();
my $k = $f->_load_karr( $dir );
is $k->{command}, 'echo hello', 'command parsed';
is $k->{max_runtime}, 900, 'max_runtime parsed';
};
# ---------------------------------------------------------------------------
# Dry-run end-to-end
# ---------------------------------------------------------------------------
subtest 'run with --dry-run: does not execute' => sub {
my $repo = make_git_repo();
write_karr_file( $repo, command => 'touch __sentinel__', on_idle => 'always-run' );
my ( $cfg_dir, $cfg ) = write_config( ["$repo"] );
my $f = new_foundation( config => "$cfg", dry_run => 1, force => 1 );
# dry_run => 1 short-circuits sync, lock, command execution, state write
$f->run;
ok ! $repo->child('__sentinel__')->exists,
'sentinel not created â dry-run did not execute';
};
done_testing;
( run in 0.396 second using v1.01-cache-2.11-cpan-bbe5e583499 )