use readsight::hyphenation::{
parse_pattern_token, parse_tex, HyphenationExceptionsCollection, HyphenationOverride,
Hyphenator, LiangHyphenator, Pattern, PatternsCollection,
};
fn empty_hyphenator(left: i32, right: i32) -> LiangHyphenator {
LiangHyphenator::new(
PatternsCollection::new(),
HyphenationExceptionsCollection::new(),
left,
right,
)
}
#[test]
fn empty_word_returns_empty() {
assert_eq!(empty_hyphenator(2, 2).hyphenate(""), Vec::<String>::new());
}
#[test]
fn short_word_returned_as_is() {
assert_eq!(empty_hyphenator(2, 2).hyphenate("it"), vec!["it"]);
}
#[test]
fn exception_word_respected() {
let mut exceptions = HyphenationExceptionsCollection::new();
exceptions.add(HyphenationOverride::new("associate", "as-so-ci-ate"));
let h = LiangHyphenator::new(PatternsCollection::new(), exceptions, 2, 2);
assert_eq!(h.hyphenate("associate"), vec!["as", "so", "ci", "ate"]);
assert_eq!(h.count_syllables("associate"), 4);
}
#[test]
fn exception_case_insensitive() {
let mut exceptions = HyphenationExceptionsCollection::new();
exceptions.add(HyphenationOverride::new("table", "ta-ble"));
let h = LiangHyphenator::new(PatternsCollection::new(), exceptions, 2, 2);
assert_eq!(h.hyphenate("TABLE"), vec!["TA", "BLE"]);
}
#[test]
fn user_hyphenation_overrides_patterns() {
let h = empty_hyphenator(2, 2);
h.add_hyphenations([("custom", "cus-tom")]);
assert_eq!(h.hyphenate("custom"), vec!["cus", "tom"]);
}
#[test]
fn count_syllables_edge_cases() {
let h = empty_hyphenator(2, 2);
assert_eq!(h.count_syllables(""), 0);
assert_eq!(h.count_syllables("it"), 1);
}
#[test]
fn pattern_based_splitting() {
let mut patterns = PatternsCollection::new();
patterns.add(Pattern::new(vec!["a".into(), "n".into()], vec![0, 3, 0]));
let h = LiangHyphenator::new(patterns, HyphenationExceptionsCollection::new(), 1, 1);
assert_eq!(h.hyphenate("banana"), vec!["ba", "na", "na"]);
}
#[test]
fn pattern_fields() {
let p = Pattern::new(vec!["a".into(), "c".into(), "h".into()], vec![0, 2, 0, 0]);
assert_eq!(p.length, 3);
assert_eq!(p.chars, vec!["a", "c", "h"]);
assert_eq!(p.weights, vec![0, 2, 0, 0]);
}
#[test]
fn patterns_collection_semantics() {
let mut c = PatternsCollection::new();
assert!(c.is_empty());
c.add(Pattern::new(
vec!["a".into(), "c".into(), "h".into()],
vec![0, 2, 0, 0],
));
c.add(Pattern::new(vec![".".into(), "a".into()], vec![0, 0, 4]));
assert_eq!(c.count(), 2);
assert_eq!(c.max_length(), 3);
assert_eq!(c.get_weights("ach"), Some(&[0, 2, 0, 0][..]));
assert_eq!(c.get_weights("zz"), None);
assert!(!c.is_empty());
}
#[test]
fn exceptions_collection_semantics() {
let mut c = HyphenationExceptionsCollection::new();
assert!(c.is_empty());
c.add(HyphenationOverride::new("hyphenated", "hy-phen-ated"));
assert!(c.has("hyphenated"));
assert_eq!(c.get("hyphenated"), Some("hy-phen-ated"));
assert_eq!(c.get("missing"), None);
assert_eq!(c.count(), 1);
assert!(!c.is_empty());
}
#[test]
fn parse_pattern_token_examples() {
let a2ch = parse_pattern_token("a2ch").unwrap();
assert_eq!(a2ch.chars, vec!["a", "c", "h"]);
assert_eq!(a2ch.weights, vec![0, 2, 0, 0]);
let dot = parse_pattern_token(".ach4").unwrap();
assert_eq!(dot.chars, vec![".", "a", "c", "h"]);
assert_eq!(dot.weights, vec![0, 0, 0, 0, 4]);
assert!(parse_pattern_token("abc").is_none()); assert!(parse_pattern_token("123").is_none()); assert!(parse_pattern_token("").is_none());
}
#[test]
fn parse_tex_patterns_and_hyphenation() {
let tex = "\\patterns{\na1b\n.ach4\n}\n\\hyphenation{\nas-so-ciate\n}\n% a comment\n";
let loaded = parse_tex(tex);
assert!(loaded.patterns.count() >= 2);
assert_eq!(loaded.patterns.get_weights("ab"), Some(&[0, 1, 0][..]));
assert_eq!(loaded.max_pattern_length, loaded.patterns.max_length());
assert!(loaded.exceptions.has("associate"));
assert_eq!(loaded.exceptions.get("associate"), Some("as-so-ciate"));
}
#[test]
fn parse_tex_ignores_comments_and_other_commands() {
let tex = "% comment line\n\\message{hello}\n\\patterns{\na1b\n}\n";
let loaded = parse_tex(tex);
assert_eq!(loaded.patterns.get_weights("ab"), Some(&[0, 1, 0][..]));
}
#[test]
fn parse_tex_stray_backslash_and_braces() {
let tex = "\\5 not a command } { \n\\patterns{\na1b\n}\n";
let loaded = parse_tex(tex);
assert_eq!(loaded.patterns.get_weights("ab"), Some(&[0, 1, 0][..]));
}
#[test]
fn split_by_hyphenation_trailing_hyphen_and_overflow() {
let h = empty_hyphenator(1, 1);
h.add_hyphenations([("abc", "a-bc-")]);
assert_eq!(h.hyphenate("abc"), vec!["a", "bc"]);
h.add_hyphenations([("abcd", "a-b-c-d-e")]);
assert_eq!(h.hyphenate("abcd"), vec!["a", "b", "c", "d"]);
}