codebook 0.3.37

A code-aware spell checker library (dependency for codebook-lsp)
Documentation
use codebook::{
    parser::{TextRange, WordLocation},
    queries::LanguageType,
};

mod utils;

#[test]
fn test_ocaml_location() {
    utils::init_logging();
    let sample_text = r#"
(* Commment with a typo *)
type usr_recrod = {
  name: string;
  agge: int;
}
let greet_usr (persn : usr_recrod) =
  let msega = "Helllo " ^ persn.name in
  print_endline msega
let () =
  let u = { name = "Alise"; agge = 30 } in
  greet_usr u
"#;

    let expected = vec![
        WordLocation::new(
            "Commment".to_string(),
            vec![TextRange {
                start_byte: 4,
                end_byte: 12,
            }],
        ),
        WordLocation::new(
            "recrod".to_string(),
            vec![
                // type definition
                TextRange {
                    start_byte: 37,
                    end_byte: 43,
                },
                // parameter annotation in greet_usr
                TextRange {
                    start_byte: 106,
                    end_byte: 112,
                },
            ],
        ),
        WordLocation::new(
            "agge".to_string(),
            vec![
                // field definition
                TextRange {
                    start_byte: 66,
                    end_byte: 70,
                },
                // field assignment in let u = { ... }
                TextRange {
                    start_byte: 215,
                    end_byte: 219,
                },
            ],
        ),
        WordLocation::new(
            "persn".to_string(),
            vec![TextRange {
                start_byte: 94,
                end_byte: 99,
            }],
        ),
        WordLocation::new(
            "msega".to_string(),
            vec![TextRange {
                start_byte: 122,
                end_byte: 127,
            }],
        ),
        WordLocation::new(
            "Helllo".to_string(),
            vec![TextRange {
                start_byte: 131,
                end_byte: 137,
            }],
        ),
        WordLocation::new(
            "Alise".to_string(),
            vec![TextRange {
                start_byte: 207,
                end_byte: 212,
            }],
        ),
    ];

    let not_expected = [
      "and", "as", "assert", "begin", "class", "constraint", "do", "done", "downto", "effect",
      "else", "end", "exception", "external", "for", "fun", "function", "functor", "if", "in",
      "include", "inherit", "initializer", "lazy", "let", "match", "method", "module",
      "mutable", "new", "nonrec", "object", "of", "open", "private", "rec", "sig", "struct",
      "then", "to", "try", "type", "val", "virtual", "when", "while", "with",
    ];

    let processor = utils::get_processor();
    let misspelled = processor
        .spell_check(sample_text, Some(LanguageType::OCaml), None)
        .to_vec();

    println!("Misspelled words: {misspelled:?}");

    for e in &expected {
        println!("Expecting: {e:?}");
        let miss = misspelled.iter().find(|r| r.word == e.word).unwrap();
        assert!(miss.locations.len() == e.locations.len());
        for location in &miss.locations {
            assert!(e.locations.contains(location));
        }
    }

    for result in misspelled {
        assert!(!not_expected.contains(&result.word.as_str()));
    }
}