Files
duckbrain-toolbox/tests/group3_state_test.php
T
2026-10-05 15:08:39 -03:00

103 lines
3.6 KiB
PHP

<?php
use Toolbox\Destination;
use Toolbox\Drift;
use Toolbox\Lock;
use Toolbox\Ownership;
use Toolbox\ProjectManifest;
Harness::suite('group3');
Harness::it('manifest de deseo guarda y recupera restricciones', function () {
$dir = tmpdir();
$m = ProjectManifest::load($dir);
$m->setConstraint('http:aria2', '^1.2');
$m->coreConstraint = '>=1.1';
$m->save($dir);
$loaded = ProjectManifest::load($dir);
eq('^1.2', $loaded->constraint('http:aria2'));
eq('>=1.1', $loaded->coreConstraint);
rrmdir($dir);
});
Harness::it('lock guarda core y componentes con schema esperado', function () {
$dir = tmpdir();
$file = $dir . '/src/Libs/Aria2.php';
write_file($file, "<?php\n");
$lock = Lock::empty();
$lock->setCore(['version' => '1.5.0', 'commit' => 'abc', 'files' => ['src/Libs/Router.php' => 'sha256:x']]);
$lock->setComponent('http:aria2', [
'package' => 'http',
'version' => '1.2.0',
'toolbox_commit' => 'D',
'mode' => 'copy',
'files' => ['src/Libs/Aria2.php' => Drift::hash($file)],
]);
$lock->save($dir);
$loaded = Lock::load($dir);
eq('1.5.0', $loaded->core()['version']);
eq('http', $loaded->component('http:aria2')['package']);
eq('copy', $loaded->component('http:aria2')['mode']);
rrmdir($dir);
});
Harness::it('ownership detecta colisión de rutas', function () {
$lock = Lock::empty();
$lock->setCore(['files' => ['src/Libs/X.php' => 'sha256:a']]);
$lock->setComponent('a:b', ['package' => 'a', 'version' => '1', 'toolbox_commit' => null, 'mode' => 'copy', 'files' => ['src/Libs/X.php' => 'sha256:b']]);
$ownership = Ownership::fromLock($lock);
ok($ownership->collisions() !== [], 'debía detectar colisión');
throws(fn () => $ownership->assertNoCollisions());
});
Harness::it('ownership separa core y componentes sin colisión', function () {
$lock = Lock::empty();
$lock->setCore(['files' => ['src/Libs/Router.php' => 'sha256:a']]);
$lock->setComponent('a:b', ['package' => 'a', 'version' => '1', 'toolbox_commit' => null, 'mode' => 'copy', 'files' => ['src/Libs/B.php' => 'sha256:b']]);
$ownership = Ownership::fromLock($lock);
eq('core', $ownership->ownerOf('src/Libs/Router.php'));
eq('a:b', $ownership->ownerOf('src/Libs/B.php'));
$ownership->assertNoCollisions();
});
Harness::it('drift distingue match, drifted y missing', function () {
$dir = tmpdir();
$file = $dir . '/f.php';
write_file($file, 'original');
$hash = Drift::hash($file);
eq(Drift::MATCH, Drift::status($file, $hash));
write_file($file, 'editado');
eq(Drift::DRIFTED, Drift::status($file, $hash));
eq(Drift::MISSING, Drift::status($dir . '/nope.php', $hash));
rrmdir($dir);
});
Harness::it('destino aplica la regla src y fuera de src', function () {
$rootDir = '/proj';
$rootCore = '/proj/src';
eq('src/Libs/Crypto.php', Destination::relative('src/Libs/Crypto.php', $rootDir, $rootCore));
eq('duckbrain', Destination::relative('duckbrain', $rootDir, $rootCore));
eq('/proj/src/Libs/Crypto.php', Destination::resolve('src/Libs/Crypto.php', $rootDir, $rootCore));
eq('/proj/duckbrain', Destination::resolve('duckbrain', $rootDir, $rootCore));
eq('custom/Libs/Crypto.php', Destination::relative('src/Libs/Crypto.php', $rootDir, '/proj/custom'));
});
Harness::it('destino explícito sobreescribe la regla', function () {
$dest = Destination::relative('src/Libs/Crypto.php', '/proj', '/proj/src', ['src/Libs/Crypto.php' => 'elsewhere/Crypto.php']);
eq('elsewhere/Crypto.php', $dest);
});