mod common;
use tempfile::TempDir;
fn stdout( out : &std::process::Output ) -> String
{
String::from_utf8_lossy( &out.stdout ).into_owned()
}
fn stderr( out : &std::process::Output ) -> String
{
String::from_utf8_lossy( &out.stderr ).into_owned()
}
fn assert_exit( out : &std::process::Output, code : i32 )
{
assert_eq!(
out.status.code().unwrap_or( -1 ),
code,
"expected exit {code}, got {:?}; stderr: {}",
out.status.code(),
stderr( out )
);
}
#[ test ]
fn ec_1_limit_5_caps_sessions()
{
let root = TempDir::new().unwrap();
let project_dir = TempDir::new().unwrap();
for i in 0..10
{
common::write_path_project_session(
root.path(),
project_dir.path(),
&format!( "sess-{i:02}" ),
2,
);
}
let out = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", root.path() )
.current_dir( project_dir.path() )
.arg( ".projects" )
.arg( "limit::5" )
.output()
.unwrap();
assert_exit( &out, 0 );
let output = stdout( &out );
let session_count = ( 0..10 )
.filter( |i| output.contains( &format!( "sess-{i:02}" ) ) )
.count();
assert!(
session_count <= 5,
"EC-1: limit::5 must show at most 5 sessions; found {session_count} in output: {output}"
);
}
#[ test ]
fn ec_2_limit_0_no_cap()
{
let root = TempDir::new().unwrap();
let project_dir = TempDir::new().unwrap();
for i in 0..10
{
common::write_path_project_session(
root.path(),
project_dir.path(),
&format!( "sess-{i:02}" ),
2,
);
}
let out_uncapped = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", root.path() )
.current_dir( project_dir.path() )
.arg( ".projects" )
.arg( "limit::0" )
.output()
.unwrap();
let out_capped = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", root.path() )
.current_dir( project_dir.path() )
.arg( ".projects" )
.arg( "limit::5" )
.output()
.unwrap();
assert_exit( &out_uncapped, 0 );
assert_exit( &out_capped, 0 );
let uncapped_len = stdout( &out_uncapped ).len();
let capped_len = stdout( &out_capped ).len();
assert!(
uncapped_len >= capped_len,
"EC-2: limit::0 output must be at least as long as limit::5 output; uncapped={uncapped_len}, capped={capped_len}"
);
}
#[ test ]
fn ec_3_limit_negative_rejected()
{
let out = common::clg_cmd()
.arg( ".projects" )
.arg( "limit::-1" )
.output()
.unwrap();
assert_exit( &out, 1 );
let combined = format!( "{}{}", stderr( &out ), stdout( &out ) );
assert!(
combined.contains( "limit" ),
"EC-3: error must mention 'limit'; got: {combined}"
);
}
#[ test ]
fn ec_4_limit_empty_rejected()
{
let out = common::clg_cmd()
.arg( ".projects" )
.arg( "limit::" )
.output()
.unwrap();
assert_exit( &out, 1 );
let combined = format!( "{}{}", stderr( &out ), stdout( &out ) );
assert!(
combined.contains( "limit" ),
"EC-4: error must mention 'limit'; got: {combined}"
);
}
#[ test ]
fn ec_5_limit_exceeds_session_count_shows_all()
{
let root = TempDir::new().unwrap();
let project_dir = TempDir::new().unwrap();
for i in 0..3
{
common::write_path_project_session(
root.path(),
project_dir.path(),
&format!( "sess-{i}" ),
2,
);
}
let out = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", root.path() )
.current_dir( project_dir.path() )
.arg( ".projects" )
.arg( "limit::100" )
.output()
.unwrap();
assert_exit( &out, 0 );
let output = stdout( &out );
for i in 0..3
{
assert!(
output.contains( &format!( "sess-{i}" ) ),
"EC-5: all 3 sessions must appear with limit::100; missing sess-{i}; got: {output}"
);
}
}
#[ test ]
fn ec_6_limit_non_integer_rejected()
{
let out = common::clg_cmd()
.arg( ".projects" )
.arg( "limit::five" )
.output()
.unwrap();
assert_exit( &out, 1 );
let combined = format!( "{}{}", stderr( &out ), stdout( &out ) );
assert!(
!combined.is_empty(),
"EC-6: expected non-empty error for non-integer limit value; got empty output"
);
}