#![cfg(any(
not(any(
feature = "parser_tests",
feature = "analyzer_tests",
feature = "codegen_tests",
feature = "interpreter_tests",
feature = "conformance_tests",
feature = "integration_tests",
)),
feature = "analyzer_tests",
))]
use windjammer::analyzer::OwnershipMode;
use windjammer::codegen::rust::copy_semantics::{CopySemantics, DerefContext};
use windjammer::parser::Type;
#[test]
fn test_primitives_are_copy() {
let semantics = CopySemantics::new();
assert!(semantics.is_type_copy(&Type::Int32));
assert!(semantics.is_type_copy(&Type::Float));
assert!(semantics.is_type_copy(&Type::Bool));
assert!(semantics.is_type_copy(&Type::Int));
assert!(semantics.is_type_copy(&Type::Uint));
}
#[test]
fn test_string_not_copy() {
let semantics = CopySemantics::new();
assert!(!semantics.is_type_copy(&Type::String));
}
#[test]
fn test_tuple_all_copy_is_copy() {
let semantics = CopySemantics::new();
let tuple = Type::Tuple(vec![Type::Int32, Type::Float, Type::Bool]);
assert!(semantics.is_type_copy(&tuple));
}
#[test]
fn test_tuple_with_noncopy_not_copy() {
let semantics = CopySemantics::new();
let tuple = Type::Tuple(vec![Type::Int32, Type::String]);
assert!(!semantics.is_type_copy(&tuple));
}
#[test]
fn test_custom_type_in_registry() {
let mut semantics = CopySemantics::new();
semantics.register_copy_type("Entity");
assert!(semantics.is_type_copy(&Type::Custom("Entity".to_string())));
}
#[test]
fn test_custom_primitive_names_copy() {
let semantics = CopySemantics::new();
assert!(semantics.is_type_copy(&Type::Custom("i32".to_string())));
assert!(semantics.is_type_copy(&Type::Custom("i64".to_string())));
assert!(semantics.is_type_copy(&Type::Custom("f32".to_string())));
assert!(semantics.is_type_copy(&Type::Custom("f64".to_string())));
assert!(semantics.is_type_copy(&Type::Custom("usize".to_string())));
assert!(semantics.is_type_copy(&Type::Custom("char".to_string())));
}
#[test]
fn test_custom_non_copy() {
let semantics = CopySemantics::new();
assert!(!semantics.is_type_copy(&Type::Custom("String".to_string())));
assert!(!semantics.is_type_copy(&Type::Custom("Vec".to_string())));
}
#[test]
fn test_option_copy_inner_is_copy() {
let semantics = CopySemantics::new();
assert!(semantics.is_type_copy(&Type::Option(Box::new(Type::Int32))));
assert!(semantics.is_type_copy(&Type::Option(Box::new(Type::Bool))));
}
#[test]
fn test_option_non_copy_inner_not_copy() {
let semantics = CopySemantics::new();
assert!(!semantics.is_type_copy(&Type::Option(Box::new(Type::String))));
}
#[test]
fn test_array_copy_inner_is_copy() {
let semantics = CopySemantics::new();
assert!(semantics.is_type_copy(&Type::Array(Box::new(Type::Int32), 4)));
}
#[test]
fn test_vec_never_copy() {
let semantics = CopySemantics::new();
assert!(!semantics.is_type_copy(&Type::Vec(Box::new(Type::Int))));
}
#[test]
fn test_reference_to_copy_is_copy() {
let semantics = CopySemantics::new();
assert!(semantics.is_type_copy(&Type::Reference(Box::new(Type::Int32))));
assert!(semantics.is_type_copy(&Type::Reference(Box::new(Type::Custom("i32".to_string())))));
assert!(semantics.is_type_copy(&Type::MutableReference(Box::new(Type::Float))));
}
#[test]
fn test_reference_to_noncopy_not_copy() {
let semantics = CopySemantics::new();
assert!(!semantics.is_type_copy(&Type::Reference(Box::new(Type::String))));
}
#[test]
fn test_qualified_custom_type_in_registry() {
let mut semantics = CopySemantics::new();
semantics.register_copy_type("module::Entity");
assert!(semantics.is_type_copy(&Type::Custom("module::Entity".to_string())));
assert!(semantics.is_type_copy(&Type::Custom("Entity".to_string())));
}
#[test]
fn test_borrowed_copy_becomes_owned() {
let semantics = CopySemantics::new();
let result = semantics.effective_ownership(OwnershipMode::Borrowed, &Type::Int32);
assert_eq!(result, OwnershipMode::Owned);
}
#[test]
fn test_mut_borrowed_copy_becomes_owned() {
let semantics = CopySemantics::new();
let result = semantics.effective_ownership(OwnershipMode::MutBorrowed, &Type::Float);
assert_eq!(result, OwnershipMode::Owned);
}
#[test]
fn test_borrowed_noncopy_stays_borrowed() {
let semantics = CopySemantics::new();
let result = semantics.effective_ownership(OwnershipMode::Borrowed, &Type::String);
assert_eq!(result, OwnershipMode::Borrowed);
}
#[test]
fn test_mut_borrowed_noncopy_stays_mut_borrowed() {
let semantics = CopySemantics::new();
let result = semantics.effective_ownership(OwnershipMode::MutBorrowed, &Type::String);
assert_eq!(result, OwnershipMode::MutBorrowed);
}
#[test]
fn test_owned_stays_owned() {
let semantics = CopySemantics::new();
let result = semantics.effective_ownership(OwnershipMode::Owned, &Type::Int32);
assert_eq!(result, OwnershipMode::Owned);
}
#[test]
fn test_borrowed_reference_to_copy_becomes_owned() {
let semantics = CopySemantics::new();
let ref_i32 = Type::Reference(Box::new(Type::Int32));
let result = semantics.effective_ownership(OwnershipMode::Borrowed, &ref_i32);
assert_eq!(result, OwnershipMode::Owned);
}
#[test]
fn test_borrowed_tuple_copy_becomes_owned() {
let semantics = CopySemantics::new();
let tuple = Type::Tuple(vec![Type::Int32, Type::Bool]);
let result = semantics.effective_ownership(OwnershipMode::Borrowed, &tuple);
assert_eq!(result, OwnershipMode::Owned);
}
#[test]
fn test_borrowed_custom_registry_copy_becomes_owned() {
let mut semantics = CopySemantics::new();
semantics.register_copy_type("Vec3");
let result =
semantics.effective_ownership(OwnershipMode::Borrowed, &Type::Custom("Vec3".to_string()));
assert_eq!(result, OwnershipMode::Owned);
}
#[test]
fn test_copy_in_comparison_no_deref() {
let semantics = CopySemantics::new();
let needs = semantics.needs_explicit_deref(
DerefContext::Comparison,
OwnershipMode::Borrowed,
&Type::Int32,
);
assert!(!needs); }
#[test]
fn test_copy_in_struct_literal_no_deref() {
let semantics = CopySemantics::new();
let needs = semantics.needs_explicit_deref(
DerefContext::StructLiteral,
OwnershipMode::Borrowed,
&Type::Float,
);
assert!(!needs); }
#[test]
fn test_noncopy_in_struct_literal_no_deref() {
let semantics = CopySemantics::new();
let needs = semantics.needs_explicit_deref(
DerefContext::StructLiteral,
OwnershipMode::Borrowed,
&Type::String,
);
assert!(!needs); }
#[test]
fn test_owned_never_needs_deref() {
let semantics = CopySemantics::new();
let needs = semantics.needs_explicit_deref(
DerefContext::Standalone,
OwnershipMode::Owned,
&Type::Int32,
);
assert!(!needs);
}
#[test]
fn test_copy_in_method_call_no_deref() {
let semantics = CopySemantics::new();
let needs = semantics.needs_explicit_deref(
DerefContext::MethodCall,
OwnershipMode::Borrowed,
&Type::Int32,
);
assert!(!needs);
}
#[test]
fn test_copy_in_field_access_no_deref() {
let semantics = CopySemantics::new();
let needs = semantics.needs_explicit_deref(
DerefContext::FieldAccess,
OwnershipMode::Borrowed,
&Type::Bool,
);
assert!(!needs);
}
#[test]
fn test_copy_in_binary_op_no_deref() {
let semantics = CopySemantics::new();
let needs = semantics.needs_explicit_deref(
DerefContext::BinaryOp,
OwnershipMode::Borrowed,
&Type::Int32,
);
assert!(!needs);
}
#[test]
fn test_copy_in_function_arg_no_deref() {
let semantics = CopySemantics::new();
let needs = semantics.needs_explicit_deref(
DerefContext::FunctionArg,
OwnershipMode::Borrowed,
&Type::Float,
);
assert!(!needs);
}
#[test]
fn test_set_copy_types_registry() {
let mut semantics = CopySemantics::new();
let mut registry = std::collections::HashSet::new();
registry.insert("MyCopy".to_string());
registry.insert("Other::Copy".to_string());
semantics.set_copy_types(®istry);
assert!(semantics.is_type_copy(&Type::Custom("MyCopy".to_string())));
assert!(semantics.is_type_copy(&Type::Custom("Copy".to_string())));
}
#[test]
fn test_deref_context_equality() {
assert_eq!(DerefContext::Comparison, DerefContext::Comparison);
assert_ne!(DerefContext::Comparison, DerefContext::MethodCall);
}
#[test]
fn test_copy_semantics_default() {
let semantics = CopySemantics::default();
assert!(semantics.is_type_copy(&Type::Int32));
assert!(!semantics.is_type_copy(&Type::String));
}