use badness::incremental::{IncrementalDatabase, QueryKind};
fn parse_count(db: &IncrementalDatabase) -> usize {
db.query_log()
.iter()
.filter(|entry| entry.kind == QueryKind::ParsedDocument)
.count()
}
#[test]
fn parsed_document_is_memoized() {
let db = IncrementalDatabase::default();
let file = db.add_file("\\section{Hi}\n");
let _ = db.parsed_tree(file);
let _ = db.parsed_tree(file);
let _ = db.parse_diagnostics(file);
assert_eq!(parse_count(&db), 1);
}
#[test]
fn editing_text_reparses() {
let mut db = IncrementalDatabase::default();
let file = db.add_file("a\n");
let _ = db.parsed_tree(file);
assert_eq!(parse_count(&db), 1);
db.set_file_text(file, "b\n");
let _ = db.parsed_tree(file);
assert_eq!(parse_count(&db), 2);
}
#[test]
fn upsert_unchanged_text_does_not_reparse() {
let mut db = IncrementalDatabase::default();
let path = std::path::Path::new("/tmp/doc.tex");
let file = db.upsert_file(path, "x\n".to_string());
let _ = db.parsed_tree(file);
assert_eq!(parse_count(&db), 1);
let same = db.upsert_file(path, "x\n".to_string());
assert!(same == file);
let _ = db.parsed_tree(same);
assert_eq!(parse_count(&db), 1);
let changed = db.upsert_file(path, "y\n".to_string());
assert!(changed == file);
let _ = db.parsed_tree(changed);
assert_eq!(parse_count(&db), 2);
}
#[test]
fn cached_tree_is_lossless() {
let db = IncrementalDatabase::default();
let input = "\\section{Hi}\n\nbody $x^2$ % c\n";
let file = db.add_file(input);
assert_eq!(db.parsed_tree(file).to_string(), input);
}
#[test]
fn remove_file_stops_tracking() {
let mut db = IncrementalDatabase::default();
let path = std::path::Path::new("/tmp/doc.tex");
let file = db.upsert_file(path, "x\n".to_string());
assert!(db.lookup_file(path) == Some(file));
assert!(db.remove_file(path) == Some(file));
assert!(db.lookup_file(path).is_none());
assert!(db.remove_file(path).is_none());
let reopened = db.upsert_file(path, "x\n".to_string());
assert!(reopened != file);
assert!(db.lookup_file(path) == Some(reopened));
}
#[test]
fn snapshot_reads_cached_parse() {
let mut db = IncrementalDatabase::default();
let path = std::path::Path::new("/tmp/snap.tex");
let file = db.upsert_file(path, "\\emph{hi}\n".to_string());
let _ = db.parsed_tree(file);
let snap = db.snapshot();
let snap_file = snap.lookup_file(path).expect("tracked file");
assert!(snap_file == file);
assert_eq!(snap.file_text(file), "\\emph{hi}\n");
assert!(snap.parse_diagnostics(file).is_empty());
assert_eq!(snap.parsed_tree(file).to_string(), "\\emph{hi}\n");
}
#[test]
fn clone_shares_storage() {
let db = IncrementalDatabase::default();
let file = db.add_file("\\emph{hi}\n");
let _ = db.parsed_tree(file);
assert_eq!(parse_count(&db), 1);
let clone = db.clone();
let _ = clone.parsed_tree(file);
assert_eq!(parse_count(&clone), 1);
assert_eq!(clone.file_text(file), "\\emph{hi}\n");
}