use std::fs;
mod cli_runner;
#[ test ]
fn info_displays_archive_metadata()
{
let temp_dir = std::env::temp_dir();
let source_dir = temp_dir.join( "test_info_source" );
let archive_path = temp_dir.join( "test_info.json" );
let _ = fs::remove_dir_all( &source_dir );
let _ = fs::remove_file( &archive_path );
fs::create_dir_all( &source_dir ).expect( "Should create source dir" );
fs::write( source_dir.join( "file1.txt" ), "Content 1" ).expect( "Should write file1" );
fs::write( source_dir.join( "file2.txt" ), "Content 2" ).expect( "Should write file2" );
fs::create_dir_all( source_dir.join( "subdir" ) ).expect( "Should create subdir" );
fs::write( source_dir.join( "subdir" ).join( "file3.txt" ), "Content 3" ).expect( "Should write file3" );
let script = format!(
".pack input::{} output::{}\n\
.archive.load path::{}\n\
.info\n\
exit",
source_dir.display(),
archive_path.display(),
archive_path.display()
);
let output = cli_runner::repl_command( &script )
.output()
.expect( "Info workflow should execute" );
let stdout = String::from_utf8_lossy( &output.stdout );
let stderr = String::from_utf8_lossy( &output.stderr );
assert!( output.status.success(), "Workflow should succeed. stdout: {stdout}, stderr: {stderr}" );
assert!( stdout.contains( "test_info_source" ) || stdout.contains( "Archive" ), "Should show archive name" );
assert!( stdout.contains( '3' ) || stdout.contains( "Files" ), "Should show file count (3 files)" );
let _ = fs::remove_dir_all( &source_dir );
let _ = fs::remove_file( &archive_path );
}
#[ test ]
fn discover_parameters_finds_template_variables()
{
let temp_dir = std::env::temp_dir();
let source_dir = temp_dir.join( "test_discover_source" );
let archive_path = temp_dir.join( "test_discover.json" );
let _ = fs::remove_dir_all( &source_dir );
let _ = fs::remove_file( &archive_path );
fs::create_dir_all( &source_dir ).expect( "Should create source dir" );
fs::write(
source_dir.join( "template1.txt" ),
"Project: {{project_name}}\nVersion: {{version}}"
).expect( "Should write template1" );
fs::write(
source_dir.join( "template2.txt" ),
"Author: {{author}}\nLicense: {{license}}\nProject: {{project_name}}"
).expect( "Should write template2" );
let script = format!(
".pack input::{} output::{}\n\
.archive.load path::{}\n\
.discover.parameters\n\
exit",
source_dir.display(),
archive_path.display(),
archive_path.display()
);
let output = cli_runner::repl_command( &script )
.output()
.expect( "Discover workflow should execute" );
let stdout = String::from_utf8_lossy( &output.stdout );
let stderr = String::from_utf8_lossy( &output.stderr );
assert!( output.status.success(), "Workflow should succeed. stdout: {stdout}, stderr: {stderr}" );
assert!( stdout.contains( "project_name" ), "Should discover project_name parameter" );
assert!( stdout.contains( "version" ), "Should discover version parameter" );
assert!( stdout.contains( "author" ), "Should discover author parameter" );
assert!( stdout.contains( "license" ), "Should discover license parameter" );
assert!( stdout.contains( '4' ) || stdout.contains( "parameters" ), "Should show parameter count" );
let _ = fs::remove_dir_all( &source_dir );
let _ = fs::remove_file( &archive_path );
}
#[ test ]
fn status_shows_archive_readiness()
{
let temp_dir = std::env::temp_dir();
let source_dir = temp_dir.join( "test_status_source" );
let archive_path = temp_dir.join( "test_status.json" );
let _ = fs::remove_dir_all( &source_dir );
let _ = fs::remove_file( &archive_path );
fs::create_dir_all( &source_dir ).expect( "Should create source dir" );
fs::write( source_dir.join( "template.txt" ), "Name: {{name}}" )
.expect( "Should write template" );
let script = format!(
".pack input::{} output::{}\n\
.archive.load path::{}\n\
.parameter.add name::name mandatory::1\n\
.status\n\
exit",
source_dir.display(),
archive_path.display(),
archive_path.display()
);
let output = cli_runner::repl_command( &script )
.output()
.expect( "Status workflow should execute" );
let stdout = String::from_utf8_lossy( &output.stdout );
let stderr = String::from_utf8_lossy( &output.stderr );
assert!( output.status.success(), "Workflow should succeed. stdout: {stdout}, stderr: {stderr}" );
assert!( stdout.contains( "name" ) || stdout.contains( "parameter" ), "Should show parameter name" );
assert!( stdout.contains( "mandatory" ) || stdout.contains( "required" ) || stdout.contains( '1' ), "Should indicate mandatory status" );
let _ = fs::remove_dir_all( &source_dir );
let _ = fs::remove_file( &archive_path );
}
#[ test ]
fn analyze_provides_comprehensive_overview()
{
let temp_dir = std::env::temp_dir();
let source_dir = temp_dir.join( "test_analyze_source" );
let archive_path = temp_dir.join( "test_analyze.json" );
let _ = fs::remove_dir_all( &source_dir );
let _ = fs::remove_file( &archive_path );
fs::create_dir_all( &source_dir ).expect( "Should create source dir" );
fs::write( source_dir.join( "file1.txt" ), "Content {{var1}}" )
.expect( "Should write file1" );
fs::write( source_dir.join( "file2.txt" ), "Data {{var2}}" )
.expect( "Should write file2" );
let script = format!(
".pack input::{} output::{}\n\
.archive.load path::{}\n\
.analyze\n\
exit",
source_dir.display(),
archive_path.display(),
archive_path.display()
);
let output = cli_runner::repl_command( &script )
.output()
.expect( "Analyze workflow should execute" );
let stdout = String::from_utf8_lossy( &output.stdout );
let stderr = String::from_utf8_lossy( &output.stderr );
assert!( output.status.success(), "Workflow should succeed. stdout: {stdout}, stderr: {stderr}" );
assert!( stdout.contains( "test_analyze_source" ) || stdout.contains( "Archive" ), "Should show archive name" );
assert!( stdout.contains( '2' ) || stdout.contains( "Files" ) || stdout.contains( "file" ), "Should show file count" );
assert!( stdout.contains( "Analysis" ) || stdout.contains( "Summary" ) || stdout.contains( "Overview" ), "Should indicate analysis output" );
let _ = fs::remove_dir_all( &source_dir );
let _ = fs::remove_file( &archive_path );
}
#[ test ]
fn analysis_commands_require_loaded_archive()
{
let commands = vec![ ".info", ".discover.parameters", ".status", ".analyze" ];
for cmd in commands
{
let output = cli_runner::cargo_run_command( &[ cmd ] )
.output()
.expect( "Command should execute" );
let combined = format!(
"{}{}",
String::from_utf8_lossy( &output.stdout ),
String::from_utf8_lossy( &output.stderr )
);
assert!(
!output.status.success() || combined.contains( "ERROR" ) || combined.contains( "No archive" ) || combined.contains( "load" ),
"{cmd} should fail or error without loaded archive. output: {combined}"
);
}
}