use badness::incremental::{IncrementalDatabase, QueryKind, SourceFile};
use badness::semantic::{RefCommand, SemanticModel};
fn model_count(db: &IncrementalDatabase) -> usize {
db.query_log()
.iter()
.filter(|entry| entry.kind == QueryKind::SemanticModel)
.count()
}
fn snapshot(db: &IncrementalDatabase, file: SourceFile) -> Snapshot {
project(db.semantic_model(file))
}
#[derive(Debug, PartialEq, Eq)]
struct Snapshot {
labels: Vec<(String, bool)>,
refs: Vec<(String, RefCommand, bool)>,
}
fn project(model: &SemanticModel) -> Snapshot {
Snapshot {
labels: model
.labels()
.iter()
.map(|l| (l.name.to_string(), l.referenced))
.collect(),
refs: model
.refs()
.iter()
.map(|r| (r.name.to_string(), r.command, r.resolved))
.collect(),
}
}
#[test]
fn semantic_model_is_memoized() {
let db = IncrementalDatabase::default();
let file = db.add_file("\\label{a}\\ref{a}\n");
let _ = db.semantic_model(file);
let _ = db.semantic_model(file);
let _ = db.semantic_model(file);
assert_eq!(model_count(&db), 1);
}
#[test]
fn editing_labels_rebuilds_model() {
let mut db = IncrementalDatabase::default();
let file = db.add_file("\\label{a}\n");
let _ = db.semantic_model(file);
assert_eq!(model_count(&db), 1);
db.set_file_text(file, "\\label{a}\\ref{a}\n");
let _ = db.semantic_model(file);
assert_eq!(model_count(&db), 2);
}
#[test]
fn whitespace_edit_yields_equal_model() {
let mut db = IncrementalDatabase::default();
let file = db.add_file("\\label{a}\\ref{a}\n");
let before = snapshot(&db, file);
db.set_file_text(file, "\\label{a}\\ref{a}\n\nsome text.\n");
let after = snapshot(&db, file);
assert_eq!(before, after);
}
#[test]
fn label_edit_changes_model_value() {
let mut db = IncrementalDatabase::default();
let file = db.add_file("\\label{a}\\ref{a}\n");
let before = snapshot(&db, file);
db.set_file_text(file, "\\label{b}\\ref{a}\n");
let after = snapshot(&db, file);
assert_ne!(before, after);
}