use std::str::FromStr;
use arcstr::ArcStr;
use rstest::{fixture, rstest};
use super::*;
use super::annot_store::EntryTree;
use crate::data_structs::annotation::gff_entry::RawGffEntry;
use crate::data_structs::typedef::BsxSmallStr;
#[test]
fn test_gff_entry_attributes_serialization() {
let mut attributes = GffEntryAttributes::default();
attributes.id = Some("gene123".into());
attributes.name = Some(vec!["my_gene".into()]);
attributes
.other
.insert("custom".to_string(), "value".to_string());
let serialized = attributes.to_string();
assert_eq!(serialized, "ID=gene123;Name=my_gene;custom=value");
}
#[test]
fn test_gff_entry_attributes_deserialization() {
let gff_string =
"ID=gene123;Name=my_gene;Alias=another_name,other_name;custom=value;";
let deserialized = GffEntryAttributes::from_str(gff_string).unwrap();
let mut expected_attributes = GffEntryAttributes::default();
expected_attributes.id = Some("gene123".into());
expected_attributes.name = Some(vec!["my_gene".into()]);
expected_attributes.alias = Some(vec!["another_name".into(), "other_name".into()]);
expected_attributes
.other
.insert("custom".to_string(), "value".to_string());
assert_eq!(deserialized, expected_attributes);
}
#[test]
fn test_raw_gff_entry_conversion() {
let raw_gff_entry = RawGffEntry {
seqid: "chr1".into(),
source: "test".into(),
feature_type: "gene".into(),
start: 100,
end: 200,
score: Some(0.9),
strand: '+',
phase: Some(0),
attributes: "ID=gene123".to_string(),
};
let gff_entry = GffEntry::try_from(raw_gff_entry).unwrap();
assert_eq!(
gff_entry.contig.seqname().to_owned(),
BsxSmallStr::from_str("chr1").unwrap()
);
assert_eq!(gff_entry.contig.start(), 100);
assert_eq!(gff_entry.contig.end(), 200);
assert_eq!(gff_entry.source, ArcStr::from("test"));
assert_eq!(gff_entry.feature_type, ArcStr::from("gene"));
assert_eq!(gff_entry.score, Some(0.9));
assert_eq!(gff_entry.phase, Some(0));
assert_eq!(gff_entry.attributes.id, Some("gene123".into()));
}
#[fixture]
fn entry_tree_entries() -> Vec<(EntryId, Option<EntryId>)> {
vec![
(1.into(), None),
(2.into(), Some(1.into())),
(3.into(), Some(1.into())),
(4.into(), Some(2.into())),
(5.into(), Some(2.into())),
(6.into(), Some(3.into())),
]
}
#[fixture]
fn simple_entry_tree(entry_tree_entries: Vec<(EntryId, Option<EntryId>)>) -> EntryTree {
let mut tree = EntryTree::new();
tree.append(entry_tree_entries).unwrap();
tree
}
#[rstest]
fn test_entry_tree_from_iter(entry_tree_entries: Vec<(EntryId, Option<EntryId>)>) {
let tree = EntryTree::from_iter(entry_tree_entries);
assert_eq!(tree.get_parent(1), Some(u64::MAX.into())); assert_eq!(tree.get_parent(2), Some(1.into()));
assert_eq!(tree.get_parent(3), Some(1.into()));
assert_eq!(tree.get_parent(4), Some(2.into()));
assert_eq!(tree.get_parent(5), Some(2.into()));
assert_eq!(tree.get_parent(6), Some(3.into()));
assert_eq!(tree.get_parent(99), None);
let mut children_of_1 = tree.get_children(1).unwrap();
children_of_1.sort();
assert_eq!(children_of_1, vec![2.into(), 3.into()]);
let mut children_of_2 = tree.get_children(2).unwrap();
children_of_2.sort();
assert_eq!(children_of_2, vec![4.into(), 5.into()]);
let mut children_of_3 = tree.get_children(3).unwrap();
children_of_3.sort();
assert_eq!(children_of_3, vec![6.into()]);
assert!(tree.get_children(4).unwrap().is_empty()); assert!(tree.get_children(99).is_none());
let mut children_of_internal_root = tree.get_children(u64::MAX).unwrap();
children_of_internal_root.sort();
assert_eq!(children_of_internal_root, vec![1.into()]);
}
#[rstest]
fn test_entry_tree_append_existing_parents(mut simple_entry_tree: EntryTree) {
let new_entries = vec![
(7.into(), Some(1.into())), (8.into(), Some(4.into())), ];
simple_entry_tree.append(new_entries).unwrap();
assert_eq!(simple_entry_tree.get_parent(7), Some(1.into()));
assert_eq!(simple_entry_tree.get_parent(8), Some(4.into()));
let mut children_of_1 = simple_entry_tree.get_children(1).unwrap();
children_of_1.sort();
assert_eq!(children_of_1, vec![2.into(), 3.into(), 7.into()]);
let mut children_of_4 = simple_entry_tree.get_children(4).unwrap();
children_of_4.sort();
assert_eq!(children_of_4, vec![8.into()]);
simple_entry_tree.append(vec![(9.into(), None)]).unwrap();
assert_eq!(simple_entry_tree.get_parent(9), Some(u64::MAX.into()));
let mut children_of_internal_root = simple_entry_tree.get_children(u64::MAX).unwrap();
children_of_internal_root.sort();
assert!(children_of_internal_root.contains(&1.into()));
assert!(children_of_internal_root.contains(&9.into()));
}
#[rstest]
fn test_entry_tree_append_unexistent_parents(mut simple_entry_tree: EntryTree) {
let new_entries = vec![
(10.into(), Some(99.into())), ];
let result = simple_entry_tree.append(new_entries);
assert!(result.is_err());
assert_eq!(
result.unwrap_err().to_string(),
"Some children have unexistent parents"
);
assert_eq!(simple_entry_tree.get_parent(10), None);
assert_eq!(simple_entry_tree.get_children(10), None);
}
#[rstest]
fn test_entry_tree_insert_under() {
let mut tree = EntryTree::new();
tree.insert_to_root(1).unwrap();
tree.insert_under(2, 1).unwrap();
assert_eq!(tree.get_parent(2), Some(1.into()));
let mut children_of_1 = tree.get_children(1).unwrap();
children_of_1.sort();
assert_eq!(children_of_1, vec![2.into()]);
let _ = tree.insert_under(3, 99);
tree.insert_under(4, 2).unwrap();
assert_eq!(tree.get_parent(4), Some(2.into()));
let mut children_of_2 = tree.get_children(2).unwrap();
children_of_2.sort();
assert_eq!(children_of_2, vec![4.into()]);
tree.insert_under(5, 1).unwrap();
assert_eq!(tree.get_parent(5), Some(1.into()));
let result = tree.insert_under(5, 2);
assert!(result.is_err());
let result = tree.insert_under(2, 1);
assert!(result.is_ok()); assert_eq!(tree.get_parent(2), Some(1.into())); }
#[rstest]
fn test_entry_tree_remove(mut simple_entry_tree: EntryTree) {
simple_entry_tree.remove(4).unwrap();
assert_eq!(simple_entry_tree.get_parent(4), None); let children_of_2 = simple_entry_tree.get_children(2).unwrap();
assert_eq!(children_of_2, vec![5.into()]);
simple_entry_tree.remove(2).unwrap();
assert_eq!(simple_entry_tree.get_parent(2), None); assert_eq!(simple_entry_tree.get_parent(5), None); let mut children_of_1 = simple_entry_tree.get_children(1).unwrap();
children_of_1.sort();
assert_eq!(children_of_1, vec![3.into()]);
let result = simple_entry_tree.remove(99);
assert!(result.is_err());
assert_eq!(
result.unwrap_err().to_string(),
"Such id did not exist in a tree"
);
simple_entry_tree.remove(1).unwrap();
assert_eq!(simple_entry_tree.get_parent(1), None); assert_eq!(simple_entry_tree.get_parent(3), None); assert_eq!(simple_entry_tree.get_parent(6), None);
let children_of_internal_root = simple_entry_tree.get_children(u64::MAX).unwrap();
assert!(children_of_internal_root.is_empty());
}
#[rstest]
fn test_entry_tree_get_parent(simple_entry_tree: EntryTree) {
assert_eq!(simple_entry_tree.get_parent(2), Some(1.into()));
assert_eq!(simple_entry_tree.get_parent(4), Some(2.into()));
assert_eq!(simple_entry_tree.get_parent(6), Some(3.into()));
assert_eq!(simple_entry_tree.get_parent(1), Some(u64::MAX.into()));
assert_eq!(simple_entry_tree.get_parent(99), None);
assert_eq!(simple_entry_tree.get_parent(4), Some(2.into()));
}
#[rstest]
fn test_entry_tree_get_children(simple_entry_tree: EntryTree) {
let mut children_of_1 = simple_entry_tree.get_children(1).unwrap();
children_of_1.sort();
assert_eq!(children_of_1, vec![2.into(), 3.into()]);
let mut children_of_2 = simple_entry_tree.get_children(2).unwrap();
children_of_2.sort();
assert_eq!(children_of_2, vec![4.into(), 5.into()]);
assert!(simple_entry_tree.get_children(4).unwrap().is_empty());
assert!(simple_entry_tree.get_children(5).unwrap().is_empty());
assert!(simple_entry_tree.get_children(6).unwrap().is_empty());
assert_eq!(simple_entry_tree.get_children(99), None);
let mut children_of_max_root = simple_entry_tree.get_children(u64::MAX).unwrap();
children_of_max_root.sort();
assert_eq!(children_of_max_root, vec![1.into()]);
}