use std::sync::Arc;
use wootype::core::{
method::{compute_method_set, Method, MethodSet, Receiver},
Type, TypeId, TypeKind, TypeUniverse,
};
#[test]
fn test_method_set_basic() {
let universe = Arc::new(TypeUniverse::new());
let type_id = TypeId(1000);
let typ = Type::new(type_id, TypeKind::Struct { fields: vec![] });
universe.insert_type(type_id, Arc::new(typ));
let method1 = Method {
name: Arc::from("Method1"),
sig: TypeId(100),
recv: Some(Receiver::Value),
};
let method2 = Method {
name: Arc::from("Method2"),
sig: TypeId(101),
recv: Some(Receiver::Pointer),
};
universe.register_method(type_id, Receiver::Value, method1.clone());
universe.register_method(type_id, Receiver::Pointer, method2.clone());
let value_set = universe.get_methods_for_type(type_id, Receiver::Value);
assert!(value_set.contains("Method1"));
assert!(!value_set.contains("Method2"));
let ptr_set = universe.get_methods_for_type(type_id, Receiver::Pointer);
assert!(!ptr_set.contains("Method1"));
assert!(ptr_set.contains("Method2"));
let complete = universe.get_complete_method_set(type_id);
assert!(complete.contains("Method1"));
assert!(complete.contains("Method2"));
assert_eq!(complete.len(), 2);
}
#[test]
fn test_receiver_can_call() {
assert!(Receiver::Value.can_call(Receiver::Value));
assert!(!Receiver::Value.can_call(Receiver::Pointer));
assert!(Receiver::Pointer.can_call(Receiver::Value));
assert!(Receiver::Pointer.can_call(Receiver::Pointer));
}
#[test]
fn test_method_set_union() {
let mut set1 = MethodSet::new();
let mut set2 = MethodSet::new();
set1.add(Method {
name: Arc::from("A"),
sig: TypeId(1),
recv: None,
});
set2.add(Method {
name: Arc::from("B"),
sig: TypeId(2),
recv: None,
});
set1.union(&set2);
assert!(set1.contains("A"));
assert!(set1.contains("B"));
assert_eq!(set1.len(), 2);
}
#[test]
fn test_method_set_implements() {
let mut concrete = MethodSet::new();
let mut interface = MethodSet::new();
concrete.add(Method {
name: Arc::from("A"),
sig: TypeId(1),
recv: None,
});
concrete.add(Method {
name: Arc::from("B"),
sig: TypeId(2),
recv: None,
});
interface.add(Method {
name: Arc::from("A"),
sig: TypeId(1),
recv: None,
});
assert!(concrete.implements(&interface));
assert!(!interface.implements(&concrete));
}
#[test]
fn test_interface_method_set() {
let universe = Arc::new(TypeUniverse::new());
let interface_id = TypeId(2000);
let interface_kind = TypeKind::Interface {
methods: vec![
wootype::core::types::InterfaceMethod {
name: Arc::from("Read"),
sig: TypeId(200),
},
wootype::core::types::InterfaceMethod {
name: Arc::from("Write"),
sig: TypeId(201),
},
],
embedded: vec![],
implicit: false,
};
let interface = Type::new(interface_id, interface_kind);
universe.insert_type(interface_id, Arc::new(interface));
let method_set = compute_method_set(interface_id, Receiver::Value, &universe);
assert!(method_set.contains("Read"));
assert!(method_set.contains("Write"));
assert_eq!(method_set.len(), 2);
}
#[test]
fn test_type_constraint_any() {
use wootype::core::types::TypeConstraint;
let universe = TypeUniverse::new();
let constraint = TypeConstraint::Any;
let int_type = universe.get_type(TypeId(2)).unwrap();
assert!(constraint.satisfied_by(&int_type, &universe));
}
#[test]
fn test_type_constraint_comparable() {
use wootype::core::types::TypeConstraint;
let universe = TypeUniverse::new();
let constraint = TypeConstraint::Comparable;
let int_type = universe.get_type(TypeId(2)).unwrap();
assert!(constraint.satisfied_by(&int_type, &universe));
let float_type = universe.get_type(TypeId(14)).unwrap();
assert!(!constraint.satisfied_by(&float_type, &universe));
}
#[test]
fn test_type_constraint_ordered() {
use wootype::core::types::TypeConstraint;
let universe = TypeUniverse::new();
let constraint = TypeConstraint::Ordered;
let int_type = universe.get_type(TypeId(2)).unwrap();
assert!(constraint.satisfied_by(&int_type, &universe));
}
#[test]
fn test_embedded_field_name_extraction() {
use wootype::core::types::StructField;
let universe = Arc::new(TypeUniverse::new());
let inner_id = TypeId(3000);
let inner = Type::new(
inner_id,
TypeKind::Named {
pkg_path: Arc::from(""),
name: Arc::from("Inner"),
underlying: inner_id,
},
);
universe.insert_type(inner_id, Arc::new(inner));
let struct_id = TypeId(3001);
let struct_kind = TypeKind::Struct {
fields: vec![StructField {
name: Arc::from("Inner"), typ: inner_id,
embedded: true,
tag: None,
}],
};
let struct_type = Type::new(struct_id, struct_kind);
universe.insert_type(struct_id, Arc::new(struct_type));
if let Some(typ) = universe.get_type(struct_id) {
if let TypeKind::Struct { fields } = &typ.kind {
assert_eq!(fields[0].name.as_ref(), "Inner");
assert!(fields[0].embedded);
} else {
panic!("Expected struct kind");
}
} else {
panic!("Type not found");
}
}