#[cfg(test)]
mod tests {
use rand::{rngs::StdRng, Rng, SeedableRng};
use failure::Fallible;
use crate::arc::Arc;
use crate::fst_impls::VectorFst;
use crate::fst_traits::{
ArcIterator, CoreFst, ExpandedFst, FinalStatesIterator, MutableArcIterator, MutableFst,
StateIterator, TextParser,
};
use crate::semirings::{ProbabilityWeight, Semiring};
use crate::test_data::text_fst::get_test_data_for_text_parser;
#[test]
fn test_small_fst() -> Fallible<()> {
let mut fst = VectorFst::new();
let s1 = fst.add_state();
let s2 = fst.add_state();
fst.set_start(s1)?;
let arc_1 = Arc::new(3, 5, ProbabilityWeight::new(10.0), s2);
fst.add_arc(s1, arc_1.clone())?;
assert_eq!(fst.num_arcs(s1).unwrap(), 1);
let arc_2 = Arc::new(5, 7, ProbabilityWeight::new(18.0), s2);
fst.add_arc(s1, arc_2.clone())?;
assert_eq!(fst.num_arcs(s1).unwrap(), 2);
assert_eq!(fst.arcs_iter(s1)?.count(), 2);
let mut it_s1 = fst.arcs_iter(s1)?;
let arc = it_s1.next().ok_or_else(|| format_err!("Missing arc"))?;
assert_eq!(arc_1, *arc);
let arc = it_s1.next().ok_or_else(|| format_err!("Missing arc"))?;
assert_eq!(arc_2, *arc);
let arc = it_s1.next();
assert!(arc.is_none());
let mut it_s2 = fst.arcs_iter(s2)?;
let d = it_s2.next();
assert!(d.is_none());
Ok(())
}
#[test]
fn test_mutable_iter_arcs_small() -> Fallible<()> {
let mut fst = VectorFst::new();
let s1 = fst.add_state();
let s2 = fst.add_state();
fst.set_start(s1)?;
let arc_1 = Arc::new(3, 5, ProbabilityWeight::new(10.0), s2);
fst.add_arc(s1, arc_1.clone())?;
let arc_2 = Arc::new(5, 7, ProbabilityWeight::new(18.0), s2);
fst.add_arc(s1, arc_2.clone())?;
let new_arc_1 = Arc::new(15, 29, ProbabilityWeight::new(33.0), s2 + 55);
fst.arcs_iter_mut(s1)?
.next()
.ok_or_else(|| format_err!("Missing arc"))?
.set_value(&new_arc_1);
let mut it_s1 = fst.arcs_iter(s1)?;
let arc = it_s1.next().ok_or_else(|| format_err!("Missing arc"))?;
assert_eq!(new_arc_1, *arc);
let arc = it_s1.next().ok_or_else(|| format_err!("Missing arc"))?;
assert_eq!(arc_2, *arc);
assert!(it_s1.next().is_none());
Ok(())
}
#[test]
fn test_start_states() -> Fallible<()> {
let mut fst = VectorFst::<ProbabilityWeight>::new();
let n_states = 1000;
let states: Vec<_> = (0..n_states).map(|_| fst.add_state()).collect();
assert_eq!(fst.start(), None);
fst.set_start(states[18])?;
assert_eq!(fst.start(), Some(states[18]));
fst.set_start(states[32])?;
assert_eq!(fst.start(), Some(states[32]));
Ok(())
}
#[test]
fn test_only_final_states() -> Fallible<()> {
let mut fst = VectorFst::<ProbabilityWeight>::new();
let n_states = 1000;
let states: Vec<_> = (0..n_states).map(|_| fst.add_state()).collect();
assert_eq!(fst.final_states_iter().count(), 0);
states
.iter()
.for_each(|v| fst.set_final(*v, ProbabilityWeight::one()).unwrap());
assert_eq!(fst.final_states_iter().count(), n_states);
Ok(())
}
#[test]
fn test_final_weight() -> Fallible<()> {
let mut fst = VectorFst::<ProbabilityWeight>::new();
let n_states = 1000;
let n_final_states = 300;
let mut states: Vec<_> = (0..n_states).map(|_| fst.add_state()).collect();
assert!(fst
.states_iter()
.map(|state_id| fst.final_weight(state_id))
.all(|v| v.is_none()));
let mut rg = StdRng::from_seed([53; 32]);
rg.shuffle(&mut states);
let final_states: Vec<_> = states.into_iter().take(n_final_states).collect();
final_states.iter().enumerate().for_each(|(idx, state_id)| {
fst.set_final(*state_id, ProbabilityWeight::new(idx as f32))
.unwrap()
});
assert!(final_states.iter().all(|state_id| fst.is_final(*state_id)));
assert!(final_states
.iter()
.enumerate()
.all(|(idx, state_id)| fst.final_weight(*state_id)
== Some(ProbabilityWeight::new(idx as f32))));
Ok(())
}
#[test]
fn test_del_state_arcs() -> Fallible<()> {
let mut fst = VectorFst::<ProbabilityWeight>::new();
let s1 = fst.add_state();
let s2 = fst.add_state();
fst.add_arc(s1, Arc::new(0, 0, ProbabilityWeight::one(), s2))?;
fst.add_arc(s2, Arc::new(0, 0, ProbabilityWeight::one(), s1))?;
fst.add_arc(s2, Arc::new(0, 0, ProbabilityWeight::one(), s2))?;
assert_eq!(fst.num_arcs(s1)?, 1);
assert_eq!(fst.num_arcs(s2)?, 2);
assert_eq!(fst.arcs_iter(s1)?.count(), 1);
assert_eq!(fst.arcs_iter(s2)?.count(), 2);
fst.del_state(s1)?;
assert_eq!(fst.num_arcs(0)?, 1);
let only_state = fst.states_iter().next().unwrap();
assert_eq!(fst.arcs_iter(only_state)?.count(), 1);
Ok(())
}
#[test]
fn test_deleting_twice_same_state() -> Fallible<()> {
let mut fst1 = VectorFst::<ProbabilityWeight>::new();
let s = fst1.add_state();
let mut fst2 = fst1.clone();
assert!(fst1.del_state(s).is_ok());
assert!(fst1.del_state(s).is_err());
let states_to_remove = vec![s, s];
assert!(fst2.del_states(states_to_remove.into_iter()).is_err());
Ok(())
}
#[test]
fn test_del_multiple_states() {
let mut fst1 = VectorFst::<ProbabilityWeight>::new();
let s1 = fst1.add_state();
let s2 = fst1.add_state();
let mut fst2 = fst1.clone();
assert!(fst1.del_state(s1).is_ok());
assert!(fst1.del_state(s2).is_err());
let states_to_remove = vec![s1, s2];
assert!(fst2.del_states(states_to_remove.into_iter()).is_ok());
}
#[test]
fn test_del_states_big() -> Fallible<()> {
let n_states = 1000;
let n_states_to_delete = 300;
let mut fst = VectorFst::<ProbabilityWeight>::new();
let mut states: Vec<_> = (0..n_states).map(|_| fst.add_state()).collect();
assert_eq!(fst.num_states(), n_states);
let mut rg = StdRng::from_seed([53; 32]);
rg.shuffle(&mut states);
let states_to_delete: Vec<_> = states.into_iter().take(n_states_to_delete).collect();
fst.del_states(states_to_delete)?;
assert_eq!(fst.num_states(), n_states - n_states_to_delete);
Ok(())
}
#[test]
fn test_parse_text() -> Fallible<()> {
for data in get_test_data_for_text_parser() {
let name = data.name;
let path_serialized_fst = data.path;
let vector_fst_ref = data.vector_fst;
let vector_fst = VectorFst::<ProbabilityWeight>::read_text(path_serialized_fst)?;
assert_eq!(
vector_fst, vector_fst_ref,
"Test failing for test parse text for wFST : {}",
name
);
}
Ok(())
}
#[test]
fn test_write_read_text() -> Fallible<()> {
for data in get_test_data_for_text_parser() {
let name = data.name;
let vector_fst_ref = data.vector_fst;
let text = vector_fst_ref.text()?;
let vector_fst = VectorFst::<ProbabilityWeight>::from_text_string(&text)?;
assert_eq!(
vector_fst, vector_fst_ref,
"Test failing for test write read text for wFST : {}",
name
);
}
Ok(())
}
#[test]
fn test_parse_single_final_state() -> Fallible<()> {
let parsed_fst = VectorFst::<ProbabilityWeight>::from_text_string("0\tInfinity\n")?;
let mut fst_ref: VectorFst<ProbabilityWeight> = VectorFst::new();
fst_ref.add_state();
fst_ref.set_start(0)?;
assert_eq!(parsed_fst, fst_ref);
Ok(())
}
}