readsight 1.0.1

Multilingual readability library — 86 languages, 17 formulas, TeX-based syllable counting via the Frank M. Liang algorithm.
Documentation
//! Unit tests for formula helpers (ported from the PHP suite).

use std::collections::BTreeMap;

use readsight::formula::{grade_clamp, round_to, GradeLevelInterpretation, TextStatisticsHelper};
use readsight::TextStatistics;

fn stats(word_count: i64, histogram: &[(i64, i64)]) -> TextStatistics {
    TextStatistics {
        letter_count: 0,
        word_count,
        sentence_count: 1,
        syllable_count: 0,
        polysyllable_count: 0,
        average_syllables_per_word: 0.0,
        average_words_per_sentence: 0.0,
        long_word_count: 0,
        syllable_histogram: histogram.iter().copied().collect::<BTreeMap<_, _>>(),
    }
}

#[test]
fn grade_level_boundaries() {
    let cases: &[(f64, &str)] = &[
        (-5.0, "Kindergarten"),
        (0.0, "Kindergarten"),
        (1.0, "Kindergarten"),
        (1.1, "1st Grade"),
        (2.0, "1st Grade"),
        (2.1, "2nd Grade"),
        (3.0, "2nd Grade"),
        (4.0, "3rd Grade"),
        (5.0, "4th Grade"),
        (6.0, "5th Grade"),
        (7.0, "6th Grade"),
        (8.0, "7th Grade"),
        (9.0, "8th Grade"),
        (10.0, "9th Grade"),
        (11.0, "10th Grade"),
        (12.0, "11th Grade"),
        (13.0, "12th Grade"),
        (13.1, "College"),
        (16.0, "College"),
        (16.1, "Graduate"),
        (25.0, "Graduate"),
    ];
    for (score, expected) in cases {
        assert_eq!(
            GradeLevelInterpretation::for_score(*score),
            *expected,
            "score {score}"
        );
    }
}

#[test]
fn difficult_percentage() {
    assert_eq!(
        TextStatisticsHelper::estimate_difficult_percentage(&stats(0, &[])),
        0.0
    );
    assert_eq!(
        TextStatisticsHelper::estimate_difficult_percentage(&stats(3, &[(1, 3)])),
        0.0
    );
    assert_eq!(
        TextStatisticsHelper::estimate_difficult_percentage(&stats(4, &[(2, 2), (3, 2)])),
        100.0
    );
    assert_eq!(
        TextStatisticsHelper::estimate_difficult_percentage(&stats(5, &[(1, 2), (2, 2), (3, 1)])),
        60.0
    );
    // more "easy" words than total clamps to zero
    assert_eq!(
        TextStatisticsHelper::estimate_difficult_percentage(&stats(3, &[(1, 5)])),
        0.0
    );
}

#[test]
fn round_to_half_away_from_zero() {
    assert_eq!(round_to(2.5, 0), 3.0);
    assert_eq!(round_to(-2.5, 0), -3.0);
    assert_eq!(round_to(1.005, 2), 1.0); // binary fp: 1.005 stored below, matches PHP
    assert_eq!(round_to(12.34567, 2), 12.35);
    assert_eq!(round_to(12.34567, 4), 12.3457);
}

#[test]
fn grade_clamp_bounds() {
    assert_eq!(grade_clamp(-3.0, 0.0, 19.0), 0.0);
    assert_eq!(grade_clamp(25.0, 0.0, 19.0), 19.0);
    assert_eq!(grade_clamp(7.44, 0.0, 19.0), 7.4);
}