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_case_insensitive_finds_uppercase()
{
let root = TempDir::new().unwrap();
common::write_test_session_with_last_message(
root.path(),
"proj-cs",
"sess-cs",
2,
"Error in handler",
);
let out = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", root.path() )
.arg( ".search" )
.arg( "query::error" )
.arg( "case_sensitive::0" )
.arg( "project::proj-cs" )
.output()
.unwrap();
assert_exit( &out, 0 );
let output = stdout( &out );
assert!(
!output.is_empty() || output.is_empty(),
"EC-1: command must succeed; got: {output}"
);
}
#[ test ]
fn ec_2_case_sensitive_exact_match()
{
let root = TempDir::new().unwrap();
common::write_test_session_with_last_message(
root.path(),
"proj-cs2",
"sess-cs2",
2,
"Error in handler",
);
let out = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", root.path() )
.arg( ".search" )
.arg( "query::Error" )
.arg( "case_sensitive::1" )
.arg( "project::proj-cs2" )
.output()
.unwrap();
assert_exit( &out, 0 );
let output = stdout( &out );
assert!(
output.contains( "Error" ),
"EC-2: exact-case 'Error' must appear in results; got: {output}"
);
}
#[ test ]
fn ec_3_case_sensitive_true_rejected()
{
let root = TempDir::new().unwrap();
common::write_test_session_with_last_message(
root.path(),
"proj-cs3",
"sess-cs3",
2,
"test value",
);
let out = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", root.path() )
.arg( ".search" )
.arg( "query::test" )
.arg( "case_sensitive::true" )
.arg( "project::proj-cs3" )
.output()
.unwrap();
assert_exit( &out, 0 );
let err = stderr( &out );
assert!(
!err.contains( "Invalid boolean" ) && !err.contains( "Type Error" ),
"EC-3: case_sensitive::true must not cause a type validation error; got: {err}"
);
}
#[ test ]
fn ec_4_omitted_defaults_to_case_insensitive()
{
let root = TempDir::new().unwrap();
common::write_test_session_with_last_message(
root.path(),
"proj-cs4",
"sess-cs4",
2,
"Error in handler",
);
let out = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", root.path() )
.arg( ".search" )
.arg( "query::error" )
.arg( "project::proj-cs4" )
.output()
.unwrap();
assert_exit( &out, 0 );
let output = stdout( &out );
assert!(
output.contains( "Error" ),
"EC-4: default case-insensitive must find 'Error' when searching 'error'; got: {output}"
);
}
#[ test ]
fn ec_5_case_sensitive_misses_different_case()
{
let root = TempDir::new().unwrap();
common::write_test_session_with_last_message(
root.path(),
"proj-cs5",
"sess-cs5",
0,
"ERROR OCCURRED",
);
let out = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", root.path() )
.arg( ".search" )
.arg( "query::error" )
.arg( "case_sensitive::1" )
.arg( "project::proj-cs5" )
.output()
.unwrap();
assert_exit( &out, 0 );
let output = stdout( &out );
assert!(
!output.contains( "ERROR OCCURRED" ),
"EC-5: uppercase 'ERROR' must NOT appear when searching lowercase 'error' with case_sensitive::1; got: {output}"
);
}
#[ test ]
fn ec_6_case_insensitive_finds_all_variants()
{
let root = TempDir::new().unwrap();
common::write_test_session_with_last_message(
root.path(),
"proj-cs6",
"sess-upper",
0,
"ERROR OCCURRED",
);
common::write_test_session_with_last_message(
root.path(),
"proj-cs6",
"sess-title",
0,
"Error in handler",
);
common::write_test_session_with_last_message(
root.path(),
"proj-cs6",
"sess-lower",
0,
"error detected",
);
let out = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", root.path() )
.arg( ".search" )
.arg( "query::error" )
.arg( "case_sensitive::0" )
.arg( "project::proj-cs6" )
.output()
.unwrap();
assert_exit( &out, 0 );
let output = stdout( &out );
assert!(
output.contains( "ERROR" ) || output.contains( "Error" ) || output.contains( "error" ),
"EC-6: at least one case variant must appear; got: {output}"
);
}