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 int_1_no_args_shows_current_project_sessions()
{
let root = TempDir::new().unwrap();
let cwd = TempDir::new().unwrap();
common::write_path_project_session(
root.path(), cwd.path(), "-default_topic", 4
);
let out = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", root.path() )
.current_dir( cwd.path() )
.arg( ".show" )
.output()
.unwrap();
assert_exit( &out, 0 );
let s = stdout( &out );
assert!(
!s.is_empty(),
"INT-1: .show with no args must produce output for cwd project; stderr: {}",
stderr( &out )
);
assert!(
s.contains( "-default_topic" ) || s.contains( "default_topic" ),
"INT-1: session '-default_topic' must appear in .show output; got:\n{s}"
);
}
#[ test ]
fn int_2_session_id_shows_conversation_content()
{
let root = TempDir::new().unwrap();
let alpha = root.path().join( "show2-alpha" );
let encoded = common::write_path_project_session(
root.path(), &alpha, "-default_topic", 4
);
let out = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", root.path() )
.arg( ".show" )
.arg( "session_id::-default_topic" )
.arg( format!( "project::{encoded}" ) )
.output()
.unwrap();
assert_exit( &out, 0 );
let s = stdout( &out );
assert!(
s.contains( "-default_topic" ) || s.contains( "default_topic" ),
"INT-2: session_id::-default_topic must appear in .show output; got:\n{s}"
);
}
#[ test ]
fn int_3_project_param_selects_explicit_project()
{
let root = TempDir::new().unwrap();
let alpha = root.path().join( "show3-alpha" );
let beta = root.path().join( "show3-beta" );
let alpha_enc = common::write_path_project_session(
root.path(), &alpha, "alpha-sess", 2
);
common::write_path_project_session( root.path(), &beta, "beta-sess", 2 );
let out = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", root.path() )
.current_dir( root.path() )
.arg( ".show" )
.arg( format!( "project::{alpha_enc}" ) )
.output()
.unwrap();
assert_exit( &out, 0 );
let s = stdout( &out );
assert!(
s.contains( "alpha-sess" ),
"INT-3: alpha session must appear with project:: selector; got:\n{s}"
);
assert!(
!s.contains( "beta-sess" ),
"INT-3: beta session must be absent when project::alpha selected; got:\n{s}"
);
}
#[ test ]
fn int_4_session_id_and_project_show_session_in_named_project()
{
let root = TempDir::new().unwrap();
let alpha = root.path().join( "show4-alpha" );
let beta = root.path().join( "show4-beta" );
let alpha_enc = common::write_path_project_session(
root.path(), &alpha, "s1", 0
);
common::write_test_session_with_last_message(
root.path(), &alpha_enc, "s1", 0, "alpha-only-content"
);
let beta_enc = common::write_path_project_session(
root.path(), &beta, "s1", 0
);
common::write_test_session_with_last_message(
root.path(), &beta_enc, "s1", 0, "beta-only-content"
);
let out = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", root.path() )
.arg( ".show" )
.arg( "session_id::s1" )
.arg( format!( "project::{alpha_enc}" ) )
.output()
.unwrap();
assert_exit( &out, 0 );
let s = stdout( &out );
assert!(
s.contains( "s1" ),
"INT-4: session s1 header must appear; got:\n{s}"
);
}
#[ test ]
fn int_5_metadata_1_suppresses_content_shows_metadata()
{
let root = TempDir::new().unwrap();
let p = root.path().join( "show5-proj" );
let enc = common::write_path_project_session(
root.path(), &p, "-default_topic", 4
);
let out = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", root.path() )
.arg( ".show" )
.arg( "session_id::-default_topic" )
.arg( "show_metadata::1" )
.arg( format!( "project::{enc}" ) )
.output()
.unwrap();
assert_exit( &out, 0 );
let s = stdout( &out );
assert!(
!s.is_empty(),
"INT-5: show_metadata::1 must produce output; stderr: {}",
stderr( &out )
);
assert!(
!s.contains( "entry 0" ),
"INT-5: message text must be absent with show_metadata::1; got:\n{s}"
);
}
#[ test ]
fn int_6_entries_1_shows_all_session_entries()
{
let root = TempDir::new().unwrap();
let p = root.path().join( "show6-proj" );
let enc = common::write_path_project_session(
root.path(), &p, "-default_topic", 4
);
let out = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", root.path() )
.arg( ".show" )
.arg( "session_id::-default_topic" )
.arg( "show_entries::1" )
.arg( format!( "project::{enc}" ) )
.output()
.unwrap();
assert_exit( &out, 0 );
let s = stdout( &out );
assert!(
!s.is_empty(),
"INT-6: show_entries::1 must show entry content; stderr: {}",
stderr( &out )
);
assert!(
s.contains( "entry" ),
"INT-6: entry content must appear with show_entries::1; got:\n{s}"
);
}
#[ test ]
fn int_7_exit_code_2_when_cwd_has_no_project()
{
let root = TempDir::new().unwrap();
let out = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", root.path() )
.current_dir( "/tmp" )
.arg( ".show" )
.output()
.unwrap();
assert_exit( &out, 1 );
let err = stderr( &out );
assert!(
!err.is_empty(),
"INT-7: .show from unmatched cwd must emit error on stderr; got silence"
);
}
#[ test ]
fn int_8_project_param_with_path_encoded_id()
{
let root = TempDir::new().unwrap();
let proj_path = root.path().join( "show8-encoded" );
let encoded = common::write_path_project_session(
root.path(), &proj_path, "enc-session", 2
);
let out = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", root.path() )
.arg( ".show" )
.arg( format!( "project::{encoded}" ) )
.output()
.unwrap();
assert_exit( &out, 0 );
let s = stdout( &out );
assert!(
s.contains( "enc-session" ) || s.contains( &encoded ),
"INT-8: session for path-encoded project must appear; got:\n{s}"
);
}