use super::*;
use std::{ops::Range, sync::Arc};
use crate::{Annotation, HighlightCategory, SyntaxEdit};
struct TestDriver {
language: String,
parsed: bool,
}
#[cfg_attr(coverage_nightly, coverage(off))]
impl TestDriver {
fn new(language: &str) -> Self {
Self {
language: language.to_string(),
parsed: false,
}
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
impl SyntaxDriver for TestDriver {
fn language(&self) -> &str {
&self.language
}
fn parse(&mut self, _content: &str) {
self.parsed = true;
}
fn update(&mut self, _content: &str, _edit: &SyntaxEdit) {
}
fn highlights(&self, byte_range: Range<usize>) -> Vec<Annotation> {
if self.parsed {
vec![Annotation::new(
byte_range.start,
byte_range.end,
HighlightCategory::new("comment"),
)]
} else {
Vec::new()
}
}
fn is_parsed(&self) -> bool {
self.parsed
}
}
struct TestFactory;
#[cfg_attr(coverage_nightly, coverage(off))]
impl SyntaxDriverFactory for TestFactory {
fn create(&self, language_id: &str) -> Option<Box<dyn SyntaxDriver>> {
if language_id == "rust" {
Some(Box::new(TestDriver::new("rust")))
} else {
None
}
}
fn supported_languages(&self) -> Vec<&str> {
vec!["rust"]
}
fn supports(&self, language_id: &str) -> bool {
language_id == "rust"
}
}
fn buffer_id(n: usize) -> BufferId {
BufferId::from_raw(n)
}
#[test]
fn test_syntax_session_state_new() {
let state = SyntaxSessionState::new();
assert!(state.is_empty());
assert!(state.factory().is_none());
}
#[test]
fn test_syntax_session_state_session_extension() {
let state = SyntaxSessionState::create();
assert!(state.is_empty());
assert!(state.factory().is_none());
}
#[test]
fn test_set_and_get() {
let mut state = SyntaxSessionState::new();
let id = buffer_id(1);
assert!(state.get(id).is_none());
state.set(id, Box::new(TestDriver::new("rust")));
assert!(state.get(id).is_some());
assert_eq!(state.get(id).unwrap().language(), "rust");
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[test]
fn test_get_mut() {
let mut state = SyntaxSessionState::new();
let id = buffer_id(1);
state.set(id, Box::new(TestDriver::new("rust")));
if let Some(driver) = state.get_mut(id) {
assert!(!driver.is_parsed());
driver.parse("fn main() {}");
assert!(driver.is_parsed());
}
assert!(state.get(id).unwrap().is_parsed());
}
#[test]
fn test_remove() {
let mut state = SyntaxSessionState::new();
let id = buffer_id(1);
state.set(id, Box::new(TestDriver::new("rust")));
assert!(state.has_driver(id));
let removed = state.remove(id);
assert!(removed.is_some());
assert!(!state.has_driver(id));
assert!(state.get(id).is_none());
}
#[test]
fn test_set_factory() {
let mut state = SyntaxSessionState::new();
assert!(state.factory().is_none());
state.set_factory(Arc::new(TestFactory));
assert!(state.factory().is_some());
assert!(state.factory().unwrap().supports("rust"));
}
#[test]
fn test_ensure_driver_with_factory() {
let mut state = SyntaxSessionState::new();
let id = buffer_id(1);
state.set_factory(Arc::new(TestFactory));
assert!(state.ensure_driver(id, "rust", "fn main() {}"));
assert!(state.get(id).unwrap().is_parsed());
assert!(state.ensure_driver(id, "rust", ""));
}
#[test]
fn test_ensure_driver_unsupported_language() {
let mut state = SyntaxSessionState::new();
let id = buffer_id(1);
state.set_factory(Arc::new(TestFactory));
assert!(!state.ensure_driver(id, "python", "def foo(): pass"));
}
#[test]
fn test_ensure_driver_no_factory() {
let mut state = SyntaxSessionState::new();
let id = buffer_id(1);
assert!(!state.ensure_driver(id, "rust", "fn main() {}"));
}
#[test]
fn test_multiple_buffers() {
let mut state = SyntaxSessionState::new();
let id1 = buffer_id(1);
let id2 = buffer_id(2);
state.set(id1, Box::new(TestDriver::new("rust")));
state.set(id2, Box::new(TestDriver::new("python")));
assert_eq!(state.len(), 2);
assert_eq!(state.get(id1).unwrap().language(), "rust");
assert_eq!(state.get(id2).unwrap().language(), "python");
}
#[test]
fn test_clear() {
let mut state = SyntaxSessionState::new();
state.set(buffer_id(1), Box::new(TestDriver::new("rust")));
state.set(buffer_id(2), Box::new(TestDriver::new("python")));
assert_eq!(state.len(), 2);
state.clear();
assert!(state.is_empty());
}
#[test]
fn test_debug_impl() {
let mut state = SyntaxSessionState::new();
state.set(buffer_id(1), Box::new(TestDriver::new("rust")));
let debug = format!("{state:?}");
assert!(debug.contains("SyntaxSessionState"));
assert!(debug.contains("buffer_count"));
}
#[test]
fn test_get_folds_via_driver() {
let mut state = SyntaxSessionState::new();
let id = buffer_id(1);
state.set(id, Box::new(TestDriver::new("rust")));
let folds = state.get(id).map_or_else(Vec::new, SyntaxDriver::folds);
assert!(folds.is_empty());
}
#[test]
fn test_get_folds_no_driver() {
let state = SyntaxSessionState::new();
let id = buffer_id(1);
let folds = state.get(id).map_or_else(Vec::new, SyntaxDriver::folds);
assert!(folds.is_empty());
}
fn make_test_registry() -> Arc<dyn crate::LanguageRegistry> {
Arc::new(crate::DefaultLanguageRegistry::new(vec![
crate::LanguageInfo::new("rust", "Rust").with_extensions(["rs"]),
crate::LanguageInfo::new("markdown", "Markdown").with_extensions(["md"]),
]))
}
#[test]
fn test_set_and_get_registry() {
let mut state = SyntaxSessionState::new();
assert!(state.registry().is_none());
state.set_registry(make_test_registry());
assert!(state.registry().is_some());
}
#[test]
fn test_detect_language_with_registry() {
let mut state = SyntaxSessionState::new();
state.set_registry(make_test_registry());
assert_eq!(state.detect_language("main.rs"), Some("rust".to_string()));
assert_eq!(state.detect_language("README.md"), Some("markdown".to_string()));
assert_eq!(state.detect_language("file.txt"), None);
}
#[test]
fn test_detect_language_without_registry() {
let state = SyntaxSessionState::new();
assert_eq!(state.detect_language("main.rs"), None);
}
#[test]
fn test_ensure_driver_from_path_creates_driver() {
let mut state = SyntaxSessionState::new();
state.set_factory(Arc::new(TestFactory));
state.set_registry(make_test_registry());
let id = buffer_id(1);
assert!(state.ensure_driver_from_path(id, "main.rs", "fn main() {}"));
assert!(state.has_driver(id));
assert_eq!(state.get(id).unwrap().language(), "rust");
}
#[test]
fn test_ensure_driver_from_path_existing_driver() {
let mut state = SyntaxSessionState::new();
state.set_factory(Arc::new(TestFactory));
state.set_registry(make_test_registry());
let id = buffer_id(1);
state.set(id, Box::new(TestDriver::new("rust")));
assert!(state.ensure_driver_from_path(id, "main.rs", ""));
}
#[test]
fn test_ensure_driver_from_path_unknown_extension() {
let mut state = SyntaxSessionState::new();
state.set_factory(Arc::new(TestFactory));
state.set_registry(make_test_registry());
let id = buffer_id(1);
assert!(!state.ensure_driver_from_path(id, "file.txt", "hello"));
assert!(!state.has_driver(id));
}
#[test]
fn test_ensure_driver_from_path_no_registry() {
let mut state = SyntaxSessionState::new();
state.set_factory(Arc::new(TestFactory));
let id = buffer_id(1);
assert!(!state.ensure_driver_from_path(id, "main.rs", "fn main() {}"));
}
#[test]
fn test_ensure_driver_from_path_no_factory() {
let mut state = SyntaxSessionState::new();
state.set_registry(make_test_registry());
let id = buffer_id(1);
assert!(!state.ensure_driver_from_path(id, "main.rs", "fn main() {}"));
}
#[test]
fn test_ensure_driver_from_path_unsupported_language() {
let mut state = SyntaxSessionState::new();
state.set_factory(Arc::new(TestFactory)); state.set_registry(make_test_registry());
let id = buffer_id(1);
assert!(!state.ensure_driver_from_path(id, "README.md", "# Hello"));
}
#[test]
fn test_debug_with_registry() {
let mut state = SyntaxSessionState::new();
state.set_registry(make_test_registry());
let debug = format!("{state:?}");
assert!(debug.contains("has_registry"));
}