component_model 0.17.0

Revolutionary type-safe component assignment for Rust. Build complex objects with zero boilerplate using derive macros and type-driven field setting. Perfect for configuration builders, fluent APIs, and object composition patterns.
Documentation
//! Integration tests for `ComponentModel` derive macro
//!
//! ## Test Matrix: Integration and Complex Scenarios
//!
//! ### Test Factors
//! - **Struct Complexity** : Simple, Complex, Nested, Generic
//! - **Type Mixing** : Popular only, Basic only, Mixed popular+basic
//! - **Real-world Usage** : Configuration structs, Builder patterns, Data models
//! - **Default Behavior** : Auto-derivable, Custom implementations
//!
//! ### Test Combinations
//!
//! | ID    | Complexity | Type Mixing    | Usage Pattern   | Default Behavior | Expected Behavior |
//! |-------|------------|----------------|----------------|------------------|-------------------|
//! | TIC01 | Complex    | Mixed          | Configuration  | Custom Default   | All assignment styles work |
//! | TIC02 | Simple     | Popular only   | Data model     | Custom Default   | Type-specific assignments work |
//! | TIC03 | Generic    | Basic only     | Builder        | Auto Default     | Generic implementations work |
//! | TIC04 | Nested     | Mixed          | Hierarchical   | Mixed Default    | Nested assignment works |
//! | TIC05 | Real-world | All types      | App config     | Custom Default   | Production-ready usage |
//!

use core ::time ::Duration;
use core ::net ::SocketAddr;
use std ::path ::PathBuf;
use std ::collections :: { HashMap, HashSet };

/// Test module alias for aggregating crate
#[ allow(unused_imports) ]
use component_model as the_module;
use the_module :: { ComponentModel, Assign };

/// Tests complex struct with mixed popular and basic types in configuration pattern.
/// Test Combination: TIC01
#[ test ]
fn test_complex_mixed_configuration()
{
  #[ derive(Debug) ]
  #[ derive(ComponentModel) ]
  struct ServerConfig
  {
  // Popular types
  timeout: Duration,
  bind_addr: SocketAddr,
  log_path: PathBuf,
  
  // Basic types  
  name: String,
  port: u16,
  debug: bool,
 }

  impl Default for ServerConfig
  {
  fn default() -> Self
  {
   use core ::net ::Ipv4Addr;
   Self {
  timeout: Duration ::from_secs( 30 ),
  bind_addr: SocketAddr ::new( Ipv4Addr ::LOCALHOST.into(), 8080 ),
  log_path: PathBuf ::from( "/tmp/server.log" ),
  name: "default-server".to_string(),
  port: 8080,
  debug: false,
 }
 }
 }

  let mut config = ServerConfig ::default();
  
  // Test popular type assignments
  component_model_types ::Assign :: < Duration, u64 > ::assign( &mut config, 60 );
  assert_eq!( config.timeout, Duration ::from_secs( 60 ) );
  
  component_model_types ::Assign :: < PathBuf, &str > ::assign( &mut config, "/var/log/app.log" );
  assert_eq!( config.log_path, PathBuf ::from( "/var/log/app.log" ) );
  
  // Test basic type assignments (note: String assignment is ambiguous due to multiple String fields)
  // Only test unambiguous types for now
  Assign ::assign( &mut config, 9000u16 );
  assert_eq!( config.port, 9000 );
  
  // Note: bool assignment is also ambiguous in some cases, use direct assignment
  config.debug = true;
  assert!( config.debug );
  
  // Verify default values for String fields
  assert_eq!( config.name, "default-server" );
}

/// Tests struct with only popular types in data model pattern.
/// Test Combination: TIC02
#[ test ]
fn test_popular_types_only_data_model()
{
  #[ derive(Debug) ]
  #[ derive(ComponentModel) ]
  struct FileMetadata
  {
  path: PathBuf,
  access_duration: Duration,
  permissions: HashSet< String >,
  attributes: HashMap< String, String >,
 }

  impl Default for FileMetadata
  {
  fn default() -> Self
  {
   Self {
  path: PathBuf ::new(),
  access_duration: Duration ::from_secs( 0 ),
  permissions: HashSet ::new(),
  attributes: HashMap ::new(),
 }
 }
 }

  let mut metadata = FileMetadata ::default();
  
  // Test Duration assignment
  component_model_types ::Assign :: < Duration, f64 > ::assign( &mut metadata, 1.5 );
  assert_eq!( metadata.access_duration, Duration ::from_secs_f64( 1.5 ) );
  
  // Test PathBuf assignment
  component_model_types ::Assign :: < PathBuf, String > ::assign( &mut metadata, "/home/user/file.txt".to_string() );
  assert_eq!( metadata.path, PathBuf ::from( "/home/user/file.txt" ) );
  
  // Verify collections are properly initialized
  assert!( metadata.permissions.is_empty() );
  assert!( metadata.attributes.is_empty() );
}

/// Tests simple struct without generics (placeholder for future generic support).
/// Test Combination: TIC03 (modified)
#[ test ]
fn test_simple_basic_types_builder()
{
  #[ derive(Default, Debug) ]
  #[ derive(ComponentModel) ]
  struct SimpleContainer
  {
  id: String,
  count: usize,
 }

  let mut container = SimpleContainer ::default();
  
  // Test basic type assignments work
  Assign ::assign( &mut container, "container-001".to_string() );
  assert_eq!( container.id, "container-001" );
  
  Assign ::assign( &mut container, 42usize );
  assert_eq!( container.count, 42 );
}

/// Tests real-world application configuration with comprehensive type coverage.
/// Test Combination: TIC05
#[ test ]
fn test_real_world_app_config()
{
  #[ derive(Debug) ]
  #[ derive(ComponentModel) ]
  struct ApplicationConfig
  {
  // Network configuration
  server_addr: SocketAddr,
  timeout: Duration,
  
  // File system
  config_path: PathBuf,
  #[ allow( dead_code ) ]
  log_path: PathBuf,
  
  // Application settings
  app_name: String,
  version: String,
  debug_mode: bool,
  max_connections: u32,
  
  // Collections
  allowed_hosts: HashSet< String >,
  environment_vars: HashMap< String, String >,
 }

  impl Default for ApplicationConfig
  {
  fn default() -> Self
  {
   use core ::net ::Ipv4Addr;
   Self {
  server_addr: SocketAddr ::new( Ipv4Addr ::UNSPECIFIED.into(), 3000 ),
  timeout: Duration ::from_secs( 30 ),
  config_path: PathBuf ::from( "app.toml" ),
  log_path: PathBuf ::from( "app.log" ),
  app_name: "MyApp".to_string(),
  version: "1.0.0".to_string(),
  debug_mode: false,
  max_connections: 100,
  allowed_hosts: HashSet ::new(),
  environment_vars: HashMap ::new(),
 }
 }
 }

  let mut config = ApplicationConfig ::default();
  
  // Test Duration assignment with tuple
  component_model_types ::Assign :: < Duration, ( u64, u32 ) > ::assign( &mut config, ( 45, 500_000_000 ) );
  assert_eq!( config.timeout, Duration ::new( 45, 500_000_000 ) );
  
  // Test PathBuf assignments
  component_model_types ::Assign :: < PathBuf, &str > ::assign( &mut config, "/etc/myapp/config.toml" );
  assert_eq!( config.config_path, PathBuf ::from( "/etc/myapp/config.toml" ) );
  
  // Test basic type assignments (note: String and bool assignments are ambiguous due to multiple fields)
  // Only test unambiguous types for now  
  Assign ::assign( &mut config, 500u32 );
  assert_eq!( config.max_connections, 500 );
  
  // Verify default values for ambiguous type fields
  assert_eq!( config.app_name, "MyApp" );
  assert!( !config.debug_mode );
  
  // Verify all collections are initialized
  assert!( config.allowed_hosts.is_empty() );
  assert!( config.environment_vars.is_empty() );
  
  // Verify derived behavior works
  assert_eq!( config.version, "1.0.0" ); // Unchanged
  assert_eq!( config.server_addr.port(), 3000 ); // Default preserved
}