use super::*;
use crate::{Groups, Query};
use molframe_core::contract::AnalysisPolicy;
use molframe_core::io::{InputBuffer, ReadOptions};
use molframe_core::structure::Structure;
const SOURCE: &str = "data_plan\n\
loop_\n_atom_site.group_PDB\n_atom_site.id\n_atom_site.type_symbol\n\
_atom_site.label_atom_id\n_atom_site.label_comp_id\n_atom_site.label_asym_id\n\
_atom_site.label_seq_id\n_atom_site.Cartn_x\n_atom_site.Cartn_y\n_atom_site.Cartn_z\n\
ATOM 1 C CA GLY A 1 0 0 0\n\
ATOM 2 O O GLY A 1 1 0 0\n";
#[test]
fn binding_resolves_globs_to_symbols_and_matches_direct_evaluation() {
let structure = structure();
let policy =
AnalysisPolicy::default().with_identifiers(molframe_core::contract::Namespace::Label);
let query = match Query::compile("name C*") {
Ok(query) => query,
Err(findings) => panic!("compile failed: {findings:?}"),
};
let plan = query.plan(&structure, &policy);
assert!(matches!(plan.expr, PhysicalExpr::ResolvedMembership { .. }));
let result = match plan.evaluate(&structure, &policy, &Groups::new(), None) {
Ok(result) => result,
Err(findings) => panic!("physical evaluation failed: {findings:?}"),
};
assert_eq!(result.selection.iter().collect::<Vec<_>>(), vec![0]);
}
#[test]
fn constant_branches_are_folded_before_execution() {
let structure = structure();
let policy = AnalysisPolicy::default();
let query = match Query::compile("all and none") {
Ok(query) => query,
Err(findings) => panic!("compile failed: {findings:?}"),
};
assert!(matches!(
query.plan(&structure, &policy).expr,
PhysicalExpr::None
));
}
const GLYCAN: &str = "data_glycan\n\
loop_\n_atom_site.group_PDB\n_atom_site.id\n_atom_site.type_symbol\n\
_atom_site.label_atom_id\n_atom_site.label_comp_id\n_atom_site.label_asym_id\n\
_atom_site.label_seq_id\n_atom_site.auth_seq_id\n_atom_site.auth_comp_id\n\
_atom_site.auth_asym_id\n_atom_site.Cartn_x\n_atom_site.Cartn_y\n_atom_site.Cartn_z\n\
ATOM 1 N N ASN A 1 10 ASN A 0 0 0\n\
HETATM 2 C C1 NAG B . 601 NAG A 5 0 0\n\
HETATM 3 C C1 MAN B . 604 MAN A 10 0 0\n\
HETATM 4 C C2 MAN B . 604 MAN A 11 0 0\n\
HETATM 5 C C1 MAN B . 605 MAN A 12 0 0\n";
#[test]
fn branched_glycan_residues_are_selected_by_component_name() {
let input = InputBuffer::from_bytes(GLYCAN.as_bytes().to_vec());
let structure = match molframe_cif::read(&input, &ReadOptions::new()) {
Ok((structure, _)) => structure,
Err(findings) => panic!("fixture failed: {findings:?}"),
};
let policy = AnalysisPolicy::default();
for (text, expected) in [
("resname MAN", 3),
("label_resname MAN", 3),
("auth_resname MAN", 3),
("resname MAN and hetero", 3),
("resname NAG", 1),
("resname man", 0),
] {
let query = match Query::compile(text) {
Ok(query) => query,
Err(findings) => panic!("compile failed: {findings:?}"),
};
let result = match query.plan(&structure, &policy).evaluate(
&structure,
&policy,
&Groups::new(),
None,
) {
Ok(result) => result,
Err(findings) => panic!("evaluation failed: {findings:?}"),
};
assert_eq!(result.selection.iter().count(), expected, "{text}");
}
}
fn structure() -> Structure {
let input = InputBuffer::from_bytes(SOURCE.as_bytes().to_vec());
match molframe_cif::read(&input, &ReadOptions::new()) {
Ok((structure, _)) => structure,
Err(findings) => panic!("fixture failed: {findings:?}"),
}
}