'http', 'version' => '1.0.0', 'description' => 'Utilidades HTTP', 'components' => [ 'curlRequest' => ['files' => ['src/Libs/CurlRequest.php']], 'aria2' => ['files' => ['src/Libs/Aria2.php']], 'compreFace' => [ 'files' => ['src/Libs/CompreFace.php'], 'require' => ['http:curlRequest' => '>=1.0'], ], ], 'default' => $compreFaceInDefault ? ['curlRequest', 'aria2', 'compreFace'] : ['aria2'], ], JSON_PRETTY_PRINT)); write_file($dir . '/packages/http/src/Libs/CurlRequest.php', "run([$proj, '--toolbox=' . $tool, '--core-dir=' . $core, '--yes']); eq(0, $code); ok(is_file($proj . '/autoload.php')); ok(is_file($proj . '/src/Libs/Router.php')); ok(!is_file($proj . '/readme.org'), 'no copia la documentación del core'); eq('0.1.0', Lock::load($proj)->core()['version'], 'versión resuelta por tag v0.1.0'); rrmdir($proj); rrmdir($core); rrmdir($tool); }); Harness::it('add copia componente, registra lock y manifest', function () { $proj = tmpdir('proj'); $tool = g7_toolbox(); $cmd = new AddCommand(new Console()); $code = $cmd->run(['http:aria2', '--root=' . $proj, '--toolbox=' . $tool, '--yes']); eq(0, $code); ok(is_file($proj . '/src/Libs/Aria2.php'), 'archivo copiado'); $lock = Lock::load($proj); ok($lock->has('http:aria2'), 'lock registra el componente'); rrmdir($proj); rrmdir($tool); }); Harness::it('add de paquete expande default; require trae dependencia', function () { $proj = tmpdir('proj'); $tool = g7_toolbox(false); // default sólo aria2 $cmd = new AddCommand(new Console()); $cmd->run(['http:compreFace', '--root=' . $proj, '--toolbox=' . $tool, '--yes']); ok(is_file($proj . '/src/Libs/CompreFace.php')); ok(is_file($proj . '/src/Libs/CurlRequest.php'), 'dependencia require instalada'); $proj2 = tmpdir('proj2'); $cmd->run(['http', '--root=' . $proj2, '--toolbox=' . $tool, '--yes']); ok(is_file($proj2 . '/src/Libs/Aria2.php')); ok(!is_file($proj2 . '/src/Libs/CompreFace.php'), 'default sólo trae lo declarado'); rrmdir($proj); rrmdir($proj2); rrmdir($tool); }); Harness::it('remove sólo quita archivos del componente', function () { $proj = tmpdir('proj'); $core = g7_core(); $tool = g7_toolbox(); (new InstallCommand(new Console()))->run([$proj, '--toolbox=' . $tool, '--core-dir=' . $core, '--yes']); (new AddCommand(new Console()))->run(['http:aria2', '--root=' . $proj, '--toolbox=' . $tool, '--yes']); (new RemoveCommand(new Console()))->run(['http:aria2', '--root=' . $proj, '--toolbox=' . $tool, '--yes']); ok(!is_file($proj . '/src/Libs/Aria2.php'), 'archivo del componente eliminado'); ok(is_file($proj . '/src/Libs/Router.php'), 'archivo del core intacto'); rrmdir($proj); rrmdir($core); rrmdir($tool); }); Harness::it('update core sólo toca rutas del core', function () { $proj = tmpdir('proj'); $tool = g7_toolbox(); $core = g7_core('1.0.0', 'router-v1'); (new InstallCommand(new Console()))->run([$proj, '--toolbox=' . $tool, '--core-dir=' . $core, '--yes']); (new AddCommand(new Console()))->run(['http:aria2', '--root=' . $proj, '--toolbox=' . $tool, '--yes']); $core2 = g7_core('2.0.0', 'router-v2'); (new UpdateCommand(new Console()))->run(['core', '--root=' . $proj, '--toolbox=' . $tool, '--core-dir=' . $core2, '--yes']); ok(str_contains((string) file_get_contents($proj . '/src/Libs/Router.php'), 'router-v2'), 'core actualizado'); ok(is_file($proj . '/src/Libs/Aria2.php'), 'componente intacto'); eq('2.0.0', Lock::load($proj)->core()['version']); rrmdir($proj); rrmdir($tool); rrmdir($core); rrmdir($core2); }); Harness::it('list muestra instalados con versión y modo', function () { $proj = tmpdir('proj'); $tool = g7_toolbox(); (new AddCommand(new Console()))->run(['http:aria2', '--root=' . $proj, '--toolbox=' . $tool, '--yes']); $console = g7_console($stream); (new ListCommand($console))->run(['--root=' . $proj, '--toolbox=' . $tool]); rewind($stream); $output = stream_get_contents($stream); ok(str_contains($output, 'http:aria2'), 'id en la salida'); ok(str_contains($output, 'copy'), 'modo en la salida'); rrmdir($proj); rrmdir($tool); }); Harness::it('--dry-run no escribe archivos ni lock', function () { $proj = tmpdir('proj'); $tool = g7_toolbox(); (new AddCommand(new Console()))->run(['http:aria2', '--root=' . $proj, '--toolbox=' . $tool, '--yes', '--dry-run']); ok(!is_file($proj . '/src/Libs/Aria2.php'), 'no copia en dry-run'); ok(!is_file(Lock::path($proj)), 'no crea lock en dry-run'); rrmdir($proj); rrmdir($tool); }); Harness::it('core sin tags: versión desconocida y commit pineado', function () { $proj = tmpdir('proj'); $tool = g7_toolbox(); $core = g7_core(''); // repo git sin tags (new InstallCommand(new Console()))->run([$proj, '--toolbox=' . $tool, '--core-dir=' . $core, '--yes']); $lock = Lock::load($proj); eq(null, $lock->core()['version'], 'sin tags la versión es desconocida'); ok($lock->core()['commit'] !== null, 'commit pineado sin depender de tags'); rrmdir($proj); rrmdir($tool); rrmdir($core); }); Harness::it('--force resuelve drift pero no salta avisos de compatibilidad', function () { $proj = tmpdir('proj'); $tool = g7_toolbox(); // add once and edit locally (new AddCommand(new Console()))->run(['http:aria2', '--root=' . $proj, '--toolbox=' . $tool, '--yes']); write_file($proj . '/src/Libs/Aria2.php', " warning against core 0.0.0 (unknown) is OK; // set a tested value to force a warning $json = json_decode((string) file_get_contents($tool . '/packages/http/duckbrain.json'), true); $json['core'] = ['requires' => '>=1.0']; write_file($tool . '/packages/http/duckbrain.json', json_encode($json)); $stream = fopen('php://memory', 'r+'); $console = new Console($stream, $stream); $code = (new AddCommand($console))->run(['http:aria2', '--root=' . $proj, '--toolbox=' . $tool, '--yes', '--force']); eq(0, $code, 'force resuelve el drift'); rewind($stream); $output = stream_get_contents($stream); ok(str_contains($output, 'WARN'), 'sigue avisando de compatibilidad'); ok(str_contains((string) file_get_contents($proj . '/src/Libs/Aria2.php'), 'aria2'), 'sobreescribe con --force'); rrmdir($proj); rrmdir($tool); });