use creature_feature::convert::Merged;
use creature_feature::featurizers;
use creature_feature::ftzrs::misc::FrontBack;
use creature_feature::ftzrs::{bigram, bislice, bookends, for_each, gap_gram, n_slice, trigram};
use creature_feature::traits::{Ftzr, IterFtzr};
use creature_feature::HashedAs;
#[test]
fn gap_gram_short_input_yields_nothing() {
let g = gap_gram(bislice(), 3, bislice());
let v: Vec<(&str, &str)> = g.featurize("abc");
assert!(v.is_empty());
let v: Vec<(&str, &str)> = g.featurize("");
assert!(v.is_empty());
let v: Vec<(&str, &str)> = g.featurize("abcdefg");
assert_eq!(v, vec![("ab", "fg")]);
}
#[test]
fn bookends_short_input_clamps() {
let b = bookends((bislice(), 4), (trigram(), 4));
let v: Vec<FrontBack<&str, String>> = b.featurize("ab");
assert_eq!(v, vec![FrontBack::Front("ab")]);
let v: Vec<FrontBack<&str, String>> = b.featurize("");
assert!(v.is_empty());
}
#[test]
fn bookends_normal_case_unchanged() {
let ftzr = bookends((bislice(), 4), (trigram(), 4));
let feats: Vec<FrontBack<&str, String>> = ftzr.featurize("sesquipedalian");
assert_eq!(
feats,
vec![
FrontBack::Front("se"),
FrontBack::Front("es"),
FrontBack::Front("sq"),
FrontBack::Back("lia".to_string()),
FrontBack::Back("ian".to_string()),
]
);
}
#[test]
fn for_each_iterftzr_matches_visitor_path() {
let words = "one fish two fish red fish blue fish";
let fe = for_each(bislice());
let via_push: Vec<&str> = fe.featurize(words.split_ascii_whitespace());
let via_iter: Vec<&str> = fe
.iterate_features(words.split_ascii_whitespace())
.map(|g: &[u8]| std::str::from_utf8(g).unwrap())
.collect();
assert_eq!(via_push, via_iter);
assert!(!via_push.is_empty());
}
#[test]
fn featurizers_macro_hygiene() {
let two = featurizers!(bigram(), bislice());
let feats: Vec<Merged<String>> = two.featurize("abcd");
assert_eq!(feats.len(), 6);
let three = featurizers!(bigram(), bislice(), n_slice(3));
let feats: Vec<Merged<HashedAs<u64>>> = three.featurize("abcd");
assert_eq!(feats.len(), 8); }
#[test]
fn string_accumulator_single_space() {
let words: Vec<&str> = "a b c".split_ascii_whitespace().collect();
let s = n_slice(2).featurize::<&[&str], String>(&words[..]);
assert_eq!(s, "a bb c"); }
#[test]
fn minhash_accumulator_deterministic() {
let a = bigram().featurize::<[u8; 2], [HashedAs<u32>; 8]>("one fish two fish");
let b = bigram().featurize::<[u8; 2], [HashedAs<u32>; 8]>("one fish two fish");
assert_eq!(a, b);
}
#[test]
fn astokens_custom_type_flows_through_all_featurizers() {
use creature_feature::traits::AsTokens;
struct Dna(Vec<u8>);
impl AsTokens for Dna {
type Token = u8;
fn as_tokens(&self) -> &[u8] {
&self.0
}
}
let dna = Dna(b"ACGTACGT".to_vec());
let slices: Vec<&[u8]> = bislice().featurize(&dna);
assert_eq!(slices.len(), 7);
let gaps: Vec<(&[u8], &[u8])> = gap_gram(bislice(), 1, bislice()).featurize(&dna);
assert_eq!(gaps[0], (&b"AC"[..], &b"TA"[..]));
let via_str: Vec<&[u8]> = bislice().featurize("ACGTACGT");
assert_eq!(slices, via_str);
}
#[cfg(feature = "heapless")]
#[test]
fn heapless_binary_heap_accumulator() {
use heapless::binary_heap::{BinaryHeap, Max};
let heap: BinaryHeap<HashedAs<u64>, Max, 16> = bislice().featurize("hello world");
assert!(!heap.is_empty());
assert!(heap.len() <= 16);
let heap2: BinaryHeap<HashedAs<u64>, Max, 16> = bislice().featurize("hello world");
let mut a: Vec<_> = heap.into_iter().collect();
let mut b: Vec<_> = heap2.into_iter().collect();
a.sort();
b.sort();
assert_eq!(a, b);
}
#[test]
fn char_token_featurization() {
use creature_feature::ftzrs::{bigram, gap_gram};
let chars: Vec<char> = "abcde".chars().collect();
let arrs: Vec<[char; 2]> = bigram().featurize(&chars);
assert_eq!(arrs, vec![['a', 'b'], ['b', 'c'], ['c', 'd'], ['d', 'e']]);
let slices: Vec<&[char]> = bislice().featurize(&chars);
assert_eq!(slices.len(), 4);
assert_eq!(slices[0], &['a', 'b'][..]);
let strs: Vec<String> = bigram().featurize(&chars);
assert_eq!(strs, vec!["ab", "bc", "cd", "de"]);
let g = gap_gram(bigram(), 1, bigram());
let pairs: Vec<([char; 2], [char; 2])> = g.featurize(&chars);
assert_eq!(pairs[0], (['a', 'b'], ['d', 'e']));
let spairs: Vec<(String, String)> = g.featurize(&chars);
assert_eq!(spairs[0], ("ab".to_string(), "de".to_string()));
}