use std::fs;
use std::path::Path;
fn read_command_src() -> String
{
let dir_path = Path::new( "src/command" );
let file_path = Path::new( "src/command.rs" );
if dir_path.is_dir()
{
let mut content = String::new();
let mut entries : Vec<_> = fs::read_dir( dir_path )
.expect( "Failed to read src/command/ directory" )
.filter_map( | e | e.ok() )
.filter( | e |
{
e.path().extension().map_or( false, | ext | ext == "rs" )
})
.collect();
entries.sort_by_key( | e | e.path() );
for entry in entries
{
let file_content = fs::read_to_string( entry.path() )
.unwrap_or_default();
content.push_str( &file_content );
content.push( '\n' );
}
content
}
else if file_path.exists()
{
fs::read_to_string( file_path ).unwrap_or_default()
}
else
{
String::new()
}
}
fn assert_method_not_exists( _file_path : &str, method_pattern : &str, method_name : &str )
{
let content = read_command_src();
let relevant_lines : Vec< &str > = content.lines()
.filter( | line |
{
let trimmed = line.trim();
!trimmed.starts_with( "//" ) &&
!trimmed.starts_with( "///" ) &&
!trimmed.contains( "#[test]" )
})
.collect();
let relevant_content = relevant_lines.join( "\n" );
let count = relevant_content.matches( method_pattern ).count();
assert_eq!( count, 0,
"Method {method_name} should not exist in command module, found {count} occurrences" );
}
fn count_public_fields_in_struct( _file_path : &str, struct_name : &str ) -> usize
{
let content = read_command_src();
if content.is_empty()
{
return 0;
}
let lines : Vec< &str > = content.lines().collect();
let mut in_struct = false;
let mut count = 0;
for line in lines
{
if line.contains( &format!( "pub struct {struct_name}" ) )
{
in_struct = true;
continue;
}
if in_struct && line.trim().starts_with( '}' )
{
break;
}
if in_struct
{
let trimmed = line.trim();
if trimmed.starts_with( "pub " ) && !trimmed.starts_with( "pub(" )
{
count += 1;
}
}
}
count
}
#[test]
fn test_from_message_method_removed()
{
assert_method_not_exists(
"src/command.rs",
"pub fn from_message",
"from_message"
);
}
#[test]
fn test_create_method_removed()
{
assert_method_not_exists(
"src/command.rs",
"pub fn create(",
"create"
);
}
#[test]
fn test_generate_method_removed()
{
assert_method_not_exists(
"src/command.rs",
"pub fn generate(",
"generate"
);
}
#[test]
fn test_no_other_factory_methods()
{
let forbidden_factories = vec![
( "pub fn build_from(", "build_from" ),
( "pub fn from_config(", "from_config" ),
( "pub fn from_str(", "from_str" ),
( "pub fn from_parts(", "from_parts" ),
( "pub fn default_with(", "default_with" ),
( "pub fn new_with(", "new_with" ),
];
for ( pattern, name ) in forbidden_factories
{
assert_method_not_exists( "src/command.rs", pattern, name );
}
}
#[test]
fn test_only_new_constructor_exists()
{
let content = read_command_src();
let count = content.matches( "pub fn new(" ).count();
assert_eq!( count, 1,
"Should have exactly 1 new() constructor, found {count}" );
}
#[test]
fn test_with_message_is_builder_not_factory()
{
let content = read_command_src();
let with_message_line = content.lines()
.find( | line | line.contains( "pub fn with_message" ) );
if let Some( line ) = with_message_line {
assert!( line.contains( "mut self" ),
"with_message() must take mut self (builder pattern), got: {line}" );
} else {
}
}
#[test]
fn test_no_public_fields_in_command_struct()
{
let count = count_public_fields_in_struct( "src/command.rs", "ClaudeCommand" );
assert_eq!( count, 0,
"ClaudeCommand should have 0 public fields, found {count}" );
}
#[test]
fn test_message_field_is_private()
{
let content = read_command_src();
let struct_section = content
.split( "pub struct ClaudeCommand" )
.nth( 1 )
.and_then( | s | s.split( "\n}" ).next() )
.unwrap_or( "" );
let pub_message_count = struct_section.matches( "pub message:" ).count();
assert_eq!( pub_message_count, 0,
"message field should be private, found {pub_message_count} public declarations" );
}
#[test]
fn test_working_directory_field_is_private()
{
let content = read_command_src();
let struct_section = content
.split( "pub struct ClaudeCommand" )
.nth( 1 )
.and_then( | s | s.split( "\n}" ).next() )
.unwrap_or( "" );
let pub_count = struct_section.matches( "pub working_directory:" ).count();
assert_eq!( pub_count, 0,
"working_directory field should be private" );
}
#[test]
fn test_max_output_tokens_field_is_private()
{
let content = read_command_src();
let struct_section = content
.split( "pub struct ClaudeCommand" )
.nth( 1 )
.and_then( | s | s.split( "\n}" ).next() )
.unwrap_or( "" );
let pub_count = struct_section.matches( "pub max_output_tokens:" ).count();
assert_eq!( pub_count, 0,
"max_output_tokens field should be private" );
}
#[test]
fn test_all_config_fields_private()
{
let content = read_command_src();
let struct_section = content
.split( "pub struct ClaudeCommand" )
.nth( 1 )
.and_then( | s | s.split( "\n}" ).next() )
.unwrap_or( "" );
let sensitive_fields = vec![
"continue_conversation",
"auto_continue",
"telemetry",
"bash_timeout_ms",
];
for field in sensitive_fields
{
let pattern = format!( "pub {field}:" );
let count = struct_section.matches( &pattern ).count();
assert_eq!( count, 0,
"Field {field} should be private, found {count} public declarations" );
}
}
#[test]
fn test_execute_non_interactive_removed()
{
assert_method_not_exists(
"src/command.rs",
"pub fn execute_non_interactive(",
"execute_non_interactive"
);
}
#[test]
fn test_run_method_removed()
{
assert_method_not_exists(
"src/command.rs",
"pub fn run(",
"run"
);
}
#[test]
fn test_no_public_spawn_method()
{
let content = read_command_src();
let pub_spawn_count = content.matches( "pub fn spawn(" ).count();
assert_eq!( pub_spawn_count, 0,
"spawn() should not be public API" );
}
#[test]
fn test_old_execution_methods_removed()
{
let deprecated_methods = vec![
( "pub fn execute_sync(", "execute_sync" ),
( "pub fn execute_async(", "execute_async" ),
( "pub fn run_command(", "run_command" ),
( "pub fn run_interactive(", "run_interactive" ),
( "pub fn call(", "call" ),
( "pub fn invoke(", "invoke" ),
];
for ( pattern, name ) in deprecated_methods
{
assert_method_not_exists( "src/command.rs", pattern, name );
}
}
#[test]
fn test_action_mode_enum_exists()
{
let content = fs::read_to_string( "src/types.rs" )
.expect( "src/types.rs should exist with enum definitions" );
assert!( content.contains( "pub enum ActionMode" ),
"ActionMode enum should exist in src/types.rs" );
assert!( content.contains( "Ask" ), "ActionMode::Ask variant should exist" );
assert!( content.contains( "Allow" ), "ActionMode::Allow variant should exist" );
assert!( content.contains( "Deny" ), "ActionMode::Deny variant should exist" );
}
#[test]
fn test_log_level_enum_exists()
{
let content = fs::read_to_string( "src/types.rs" )
.expect( "src/types.rs should exist with enum definitions" );
assert!( content.contains( "pub enum LogLevel" ),
"LogLevel enum should exist in src/types.rs" );
assert!( content.contains( "Error" ), "LogLevel::Error variant should exist" );
assert!( content.contains( "Warn" ), "LogLevel::Warn variant should exist" );
assert!( content.contains( "Info" ), "LogLevel::Info variant should exist" );
}
#[test]
fn test_enums_used_not_strings()
{
let content = read_command_src();
let uses_action_mode = content.contains( "ActionMode" );
let uses_log_level = content.contains( "LogLevel" );
assert!( uses_action_mode || uses_log_level,
"command.rs should reference ActionMode or LogLevel enums" );
}
#[test]
fn test_old_api_usage_impossible()
{
assert_method_not_exists( "src/command.rs", "pub fn from_message", "from_message" );
assert_method_not_exists( "src/command.rs", "pub fn create(", "create" );
assert_method_not_exists( "src/command.rs", "pub fn generate(", "generate" );
let pub_fields = count_public_fields_in_struct( "src/command.rs", "ClaudeCommand" );
assert_eq!( pub_fields, 0, "Public fields make old direct-access pattern possible" );
assert_method_not_exists( "src/command.rs", "pub fn execute_non_interactive(", "execute_non_interactive" );
let types_content = fs::read_to_string( "src/types.rs" )
.expect( "src/types.rs should exist" );
assert!( types_content.contains( "pub enum ActionMode" ), "ActionMode enum required for type safety" );
assert!( types_content.contains( "pub enum LogLevel" ), "LogLevel enum required for type safety" );
}
#[test]
fn test_grep_patterns_accurate()
{
let content = read_command_src();
assert!( content.contains( "pub fn new(" ),
"Should find new() method (proves grep patterns work)" );
assert!( content.contains( "pub fn execute(" ),
"Should find execute() method (proves grep patterns work)" );
}