mod common;
#[test]
fn test_list_type_parameter_validation()
{
let output = common::clg_cmd()
.args( [ ".list", "type::invalid" ] )
.current_dir( env!( "CARGO_MANIFEST_DIR" ) )
.output()
.expect( "Failed to execute command" );
let stderr = String::from_utf8_lossy( &output.stderr );
let stdout = String::from_utf8_lossy( &output.stdout );
let combined = format!( "{stderr}{stdout}" );
assert!(
!output.status.success(),
"Command should fail with invalid type parameter"
);
assert!(
combined.contains( "Invalid type" ) || combined.contains( "invalid" ),
"Error message should mention invalid type. Got: {combined}"
);
}
#[test]
fn test_list_type_parameter_valid_values()
{
let output = common::clg_cmd()
.args( [ ".list", "type::uuid" ] )
.current_dir( env!( "CARGO_MANIFEST_DIR" ) )
.output()
.expect( "Failed to execute command" );
assert!( output.status.success(), "type::uuid should be valid" );
let output = common::clg_cmd()
.args( [ ".list", "type::path" ] )
.current_dir( env!( "CARGO_MANIFEST_DIR" ) )
.output()
.expect( "Failed to execute command" );
assert!( output.status.success(), "type::path should be valid" );
let output = common::clg_cmd()
.args( [ ".list", "type::all" ] )
.current_dir( env!( "CARGO_MANIFEST_DIR" ) )
.output()
.expect( "Failed to execute command" );
assert!( output.status.success(), "type::all should be valid" );
}
#[test]
fn test_status_verbosity_negative_validation()
{
let output = common::clg_cmd()
.args( [ ".status", "verbosity::-1" ] )
.current_dir( env!( "CARGO_MANIFEST_DIR" ) )
.output()
.expect( "Failed to execute command" );
let stderr = String::from_utf8_lossy( &output.stderr );
let stdout = String::from_utf8_lossy( &output.stdout );
let combined = format!( "{stderr}{stdout}" );
assert!(
!output.status.success(),
"Command should fail with negative verbosity. Got: {combined}"
);
assert!(
combined.contains( "verbosity" ) && combined.contains( "negative" ) || combined.contains( "range" ) || combined.contains( "0-5" ),
"Error message should mention verbosity range. Got: {combined}"
);
}
#[test]
fn test_status_verbosity_out_of_range_validation()
{
let output = common::clg_cmd()
.args( [ ".status", "verbosity::10" ] )
.current_dir( env!( "CARGO_MANIFEST_DIR" ) )
.output()
.expect( "Failed to execute command" );
let stderr = String::from_utf8_lossy( &output.stderr );
let stdout = String::from_utf8_lossy( &output.stdout );
let combined = format!( "{stderr}{stdout}" );
assert!(
!output.status.success(),
"Command should fail with out-of-range verbosity. Got: {combined}"
);
assert!(
combined.contains( "verbosity" ) && (combined.contains( "range" ) || combined.contains( "0-5" )),
"Error message should mention valid verbosity range (0-5). Got: {combined}"
);
}
#[test]
fn test_status_verbosity_valid_range()
{
let temp_dir = std::env::temp_dir().join( "test-status-verbosity-range" );
std::fs::create_dir_all( &temp_dir ).expect( "Failed to create temp dir" );
std::fs::create_dir_all( temp_dir.join( "projects" ) ).expect( "Failed to create projects dir" );
for verbosity in 0..=5
{
let output = common::clg_cmd()
.args
(
[
".status",
&format!( "verbosity::{verbosity}" ),
&format!( "path::{}", temp_dir.display() )
]
)
.current_dir( env!( "CARGO_MANIFEST_DIR" ) )
.output()
.expect( "Failed to execute command" );
assert!(
output.status.success(),
"verbosity::{verbosity} should be valid"
);
}
std::fs::remove_dir_all( &temp_dir ).ok();
}
#[test]
fn test_show_verbosity_negative_validation()
{
let output = common::clg_cmd()
.args( [ ".show", "verbosity::-1" ] )
.current_dir( env!( "CARGO_MANIFEST_DIR" ) )
.output()
.expect( "Failed to execute command" );
let stderr = String::from_utf8_lossy( &output.stderr );
let stdout = String::from_utf8_lossy( &output.stdout );
let combined = format!( "{stderr}{stdout}" );
assert!(
!output.status.success(),
"Command should fail with negative verbosity. Got: {combined}"
);
}
#[test]
fn test_show_verbosity_out_of_range_validation()
{
let output = common::clg_cmd()
.args( [ ".show", "verbosity::10" ] )
.current_dir( env!( "CARGO_MANIFEST_DIR" ) )
.output()
.expect( "Failed to execute command" );
let stderr = String::from_utf8_lossy( &output.stderr );
let stdout = String::from_utf8_lossy( &output.stdout );
let combined = format!( "{stderr}{stdout}" );
assert!(
!output.status.success(),
"Command should fail with out-of-range verbosity. Got: {combined}"
);
}
#[test]
fn test_list_min_entries_negative_validation()
{
let output = common::clg_cmd()
.args( [ ".list", "min_entries::-5" ] )
.current_dir( env!( "CARGO_MANIFEST_DIR" ) )
.output()
.expect( "Failed to execute command" );
let stderr = String::from_utf8_lossy( &output.stderr );
let stdout = String::from_utf8_lossy( &output.stdout );
let combined = format!( "{stderr}{stdout}" );
assert!(
!output.status.success(),
"Command should fail with negative min_entries. Got: {combined}"
);
assert!(
combined.contains( "min_entries" ) && combined.contains( "negative" ) || combined.contains( "positive" ),
"Error message should mention min_entries must be positive. Got: {combined}"
);
}
#[test]
fn test_show_entries_accepted_in_content_mode()
{
let output = common::clg_cmd()
.args( [ ".show", "session_id::test-session-id", "entries::1" ] )
.current_dir( env!( "CARGO_MANIFEST_DIR" ) )
.output()
.expect( "Failed to execute command" );
let stderr = String::from_utf8_lossy( &output.stderr );
let stdout = String::from_utf8_lossy( &output.stdout );
let combined = format!( "{stderr}{stdout}" );
assert!(
!combined.contains( "entries" ) || !combined.contains( "metadata mode" ),
"entries::1 must NOT be rejected as invalid in content mode. Got: {combined}"
);
}
#[test]
fn test_show_entries_works_in_metadata_mode()
{
let output = common::clg_cmd()
.args( [ ".show", "session_id::test-session-id", "metadata::1", "entries::1" ] )
.current_dir( env!( "CARGO_MANIFEST_DIR" ) )
.output()
.expect( "Failed to execute command" );
let stderr = String::from_utf8_lossy( &output.stderr );
let stdout = String::from_utf8_lossy( &output.stdout );
let combined = format!( "{stderr}{stdout}" );
assert!(
!output.status.success(),
"Command should fail (session not found), but for different reason than parameter validation"
);
let is_param_validation_error = combined.contains( "entries" ) && combined.contains( "metadata" ) && combined.contains( "only works" );
assert!(
!is_param_validation_error,
"Should fail due to missing session, NOT parameter validation. Got: {combined}"
);
}
#[ test ]
fn test_show_entries_valid_with_verbosity_zero()
{
let output = common::clg_cmd()
.args( [ ".show", "session_id::test-session-id", "verbosity::0", "entries::1" ] )
.current_dir( env!( "CARGO_MANIFEST_DIR" ) )
.output()
.expect( "Failed to execute command" );
let stderr = String::from_utf8_lossy( &output.stderr );
let stdout = String::from_utf8_lossy( &output.stdout );
let combined = format!( "{stderr}{stdout}" );
assert!(
!output.status.success(),
"Command should fail (session not found). Got: {combined}"
);
let is_mode_validation_error =
combined.contains( "entries" ) &&
combined.contains( "metadata" ) &&
combined.contains( "only works" );
assert!(
!is_mode_validation_error,
"verbosity::0 + entries::1 must pass validation, not trigger mode error. Got: {combined}"
);
}
#[test]
fn test_count_target_invalid_value()
{
let output = common::clg_cmd()
.args( [ ".count", "target::invalid" ] )
.current_dir( env!( "CARGO_MANIFEST_DIR" ) )
.output()
.expect( "Failed to execute command" );
let stderr = String::from_utf8_lossy( &output.stderr );
let stdout = String::from_utf8_lossy( &output.stdout );
let combined = format!( "{stderr}{stdout}" );
assert!(
!output.status.success(),
"Command should fail with invalid target. Got: {combined}"
);
assert!(
combined.to_lowercase().contains( "invalid" ) &&
combined.to_lowercase().contains( "target" ),
"Error should mention invalid target. Got: {combined}"
);
}
#[test]
fn test_count_target_valid_values()
{
let output = common::clg_cmd()
.args( [ ".count" ] )
.current_dir( env!( "CARGO_MANIFEST_DIR" ) )
.output()
.expect( "Failed to execute command" );
assert!( output.status.success(), "target::projects (default) should be valid" );
let output = common::clg_cmd()
.args( [ ".count", "target::projects" ] )
.current_dir( env!( "CARGO_MANIFEST_DIR" ) )
.output()
.expect( "Failed to execute command" );
assert!( output.status.success(), "target::projects should be valid" );
let output = common::clg_cmd()
.args( [ ".count", "target::sessions" ] )
.current_dir( env!( "CARGO_MANIFEST_DIR" ) )
.output()
.expect( "Failed to execute command" );
let stderr = String::from_utf8_lossy( &output.stderr );
let stdout = String::from_utf8_lossy( &output.stdout );
let combined = format!( "{stderr}{stdout}" );
assert!(
!output.status.success(),
"Command should fail (missing project parameter)"
);
assert!(
!combined.to_lowercase().contains( "invalid" ) || !combined.to_lowercase().contains( "target" ),
"Should not error on target validation. Got: {combined}"
);
assert!(
combined.to_lowercase().contains( "project" ) && combined.to_lowercase().contains( "required" ),
"Error should mention project parameter required. Got: {combined}"
);
}
#[test]
fn test_count_target_singular_form()
{
let output = common::clg_cmd()
.args( [ ".count", "target::project" ] )
.current_dir( env!( "CARGO_MANIFEST_DIR" ) )
.output()
.expect( "Failed to execute command" );
let stderr = String::from_utf8_lossy( &output.stderr );
let stdout = String::from_utf8_lossy( &output.stdout );
let combined = format!( "{stderr}{stdout}" );
assert!(
!output.status.success(),
"Command should fail with singular 'project'. Got: {combined}"
);
assert!(
combined.contains( "project" ) && (combined.contains( "valid" ) || combined.contains( "projects" )),
"Error should mention valid plural form 'projects'. Got: {combined}"
);
}
#[test]
fn test_count_target_empty_value()
{
let output = common::clg_cmd()
.args( [ ".count", "target::" ] )
.current_dir( env!( "CARGO_MANIFEST_DIR" ) )
.output()
.expect( "Failed to execute command" );
let stderr = String::from_utf8_lossy( &output.stderr );
let stdout = String::from_utf8_lossy( &output.stdout );
let combined = format!( "{stderr}{stdout}" );
assert!(
!output.status.success(),
"Command should fail with empty target. Got: {combined}"
);
}