App-Ariza.git | t/ | 03-versions.rakutest
use v6.d;
use Test;
use App::Ariza::Versions;
plan 7;
sub tmp-dir(--> IO::Path) {
my $dir = $*TMPDIR.add("ariza-versions-{$*PID}-{(^1_000_000).pick}");
$dir.mkdir;
$dir;
}
sub rm-rf(IO::Path $d) {
return unless $d.d;
.&rm-rf for $d.dir.grep(*.d);
.unlink for $d.dir.grep(*.f);
$d.rmdir;
}
sub write-toml(IO::Path $dir, Str $content --> IO::Path) {
my $path = $dir.add('versions.toml');
$path.spurt($content);
$path;
}
subtest 'the shipped pin file', {
plan 5;
my $v = App::Ariza::Versions.load;
is $v.sqlcipher, '4.14.0', 'the SQLCipher version a bundle expects';
is $v.rakudo-version, '2026.07', 'the bundled runtime version';
is $v.rakudo-revision, '01', 'the bundled runtime revision';
is $v.rakudo-tag, '2026.07-01', 'rakudo-tag joins the two';
is-deeply $v.warnings.List, (), 'the shipped file parses without warnings';
};
subtest 'load reports where it read from', {
plan 2;
my $v = App::Ariza::Versions.load;
ok $v.path.defined, 'path is populated';
is $v.path.basename, 'versions.toml', 'and names the file';
};
subtest 'unknown keys warn, they never die', {
plan 5;
my $dir = tmp-dir;
LEAVE { rm-rf($dir) }
my $path = write-toml($dir, q:to/TOML/);
sqlcipher = "4.14.0"
future-pin = "whatever"
[rakudo]
version = "2026.07"
revision = "01"
codename = "nautilus"
TOML
my $v = App::Ariza::Versions.load($path);
is $v.sqlcipher, '4.14.0', 'the recognised keys still load';
is $v.rakudo-tag, '2026.07-01', 'including the nested table';
is +$v.warnings, 2, 'both unknown keys warned';
ok $v.warnings.first(/"'future-pin'"/), 'the top-level key is named';
ok $v.warnings.first(/"'rakudo.codename'"/), 'the nested key is dotted';
};
subtest '//-prefixed keys are ignored silently', {
plan 2;
my $dir = tmp-dir;
LEAVE { rm-rf($dir) }
my $path = write-toml($dir, q:to/TOML/);
"// note" = "why this pin is stuck"
sqlcipher = "4.14.0"
[rakudo]
"// why" = "waiting on a MoarVM fix"
version = "2026.07"
revision = "01"
TOML
my $v = App::Ariza::Versions.load($path);
is-deeply $v.warnings.List, (), 'no warnings for comment keys';
is $v.sqlcipher, '4.14.0', 'and the real keys are unaffected';
};
subtest 'wrong types die naming the key', {
plan 3;
my $dir = tmp-dir;
LEAVE { rm-rf($dir) }
throws-like { App::Ariza::Versions.load(write-toml($dir, 'sqlcipher = 2026')) },
Exception, message => /'sqlcipher must be a string'/,
'a bare number where a string belongs';
throws-like {
App::Ariza::Versions.load(write-toml($dir, "[rakudo]\nversion = 2026\n"))
}, Exception, message => /'rakudo.version must be a string'/,
'the dotted path names the nested key';
throws-like { App::Ariza::Versions.load(write-toml($dir, 'rakudo = "flat"')) },
Exception, message => /'rakudo must be a table'/,
'a scalar where a table belongs';
};
subtest 'missing pins are undefined, not empty', {
plan 5;
my $dir = tmp-dir;
LEAVE { rm-rf($dir) }
my $v = App::Ariza::Versions.load(write-toml($dir, "[rakudo]\nrevision = \"01\"\n"));
is $v.sqlcipher, Str, 'an absent flat pin';
is $v.rakudo-version, Str, 'an absent nested pin';
is $v.rakudo-tag, Str, 'rakudo-tag needs both halves';
my $half = App::Ariza::Versions.load(
write-toml($dir, "[rakudo]\nversion = \"2026.07\"\n"));
is $half.rakudo-tag, Str, 'half an identity names nothing';
# The other side of the same distinction: a pin that is present but
# deliberately blank is the empty string, and stays distinguishable
# from one that was never written.
my $blank = App::Ariza::Versions.load(write-toml($dir, 'sqlcipher = ""'));
is $blank.sqlcipher, '', 'an empty pin is the empty string, not undefined';
};
subtest 'broken files fail distinguishably', {
plan 3;
my $dir = tmp-dir;
LEAVE { rm-rf($dir) }
throws-like { App::Ariza::Versions.load($dir.add('nope.toml')) },
Exception, message => /'no versions file at'/,
'a missing file';
throws-like { App::Ariza::Versions.load(write-toml($dir, "= = =\n")) },
Exception, message => /'malformed TOML in'/,
'a file that is not TOML';
my $empty = App::Ariza::Versions.load(write-toml($dir, ''));
is $empty.sqlcipher, Str, 'an empty file is a valid, empty pin set';
};