use seq_map::SeqMap;
use source_map_cache::SourceMap;
use source_map_node::Span;
use std::path::Path;
use std::path::PathBuf;
fn create_test_source_map() -> SourceMap {
SourceMap {
mounts: SeqMap::new(),
cache: SeqMap::new(),
file_cache: SeqMap::new(),
next_file_id: 1,
}
}
#[test]
fn test_basic_line_offsets() {
let mut source_map = create_test_source_map();
let file_content = "line 1\nline 2\nline 3\n";
let file_id = 1;
source_map.add_manual(file_id, "test", &PathBuf::from("test.txt"), file_content);
assert_eq!(source_map.get_source_line(file_id, 1), Some("line 1"));
assert_eq!(source_map.get_source_line(file_id, 2), Some("line 2"));
assert_eq!(source_map.get_source_line(file_id, 3), Some("line 3"));
assert_eq!(source_map.get_source_line(file_id, 4), None);
assert_eq!(source_map.get_span_location_utf8(file_id, 0), Some((1, 1))); assert_eq!(source_map.get_span_location_utf8(file_id, 7), Some((2, 1))); }
#[test]
fn test_file_without_trailing_newline() {
let mut source_map = create_test_source_map();
let file_content = "first line\nsecond line";
let file_id = 1;
source_map.add_manual(
file_id,
"test",
&PathBuf::from("no_newline.txt"),
file_content,
);
assert_eq!(source_map.get_source_line(file_id, 1), Some("first line"));
assert_eq!(source_map.get_source_line(file_id, 2), Some("second line"));
assert_eq!(source_map.get_source_line(file_id, 3), None);
let span = Span {
file_id,
offset: 11, length: 11, };
assert_eq!(source_map.get_text_span(&span), Some("second line"));
}
#[test]
fn test_empty_file_and_edge_cases() {
let mut source_map = create_test_source_map();
let empty_id = 1;
source_map.add_manual(empty_id, "test", &PathBuf::from("empty.txt"), "");
let single_id = 2;
source_map.add_manual(
single_id,
"test",
&PathBuf::from("single.txt"),
"just one line",
);
let newlines_id = 3;
source_map.add_manual(
newlines_id,
"test",
&PathBuf::from("newlines.txt"),
"\n\n\n",
);
assert_eq!(source_map.get_source_line(empty_id, 1), None);
assert_eq!(
source_map.get_source_line(single_id, 1),
Some("just one line")
);
assert_eq!(source_map.get_source_line(single_id, 2), None);
assert_eq!(source_map.get_source_line(newlines_id, 1), Some(""));
assert_eq!(source_map.get_source_line(newlines_id, 2), Some(""));
assert_eq!(source_map.get_source_line(newlines_id, 3), Some(""));
assert_eq!(source_map.get_source_line(newlines_id, 4), None);
}
#[test]
fn test_set_method_updates_both_caches() {
let mut source_map = create_test_source_map();
let mount_name = "test";
let relative_path = Path::new("test_file.txt");
let initial_contents = "initial content";
let updated_contents = "updated content";
let file_id1 = source_map.set(mount_name, relative_path, initial_contents);
assert!(source_map.cache.get(&file_id1).is_some());
assert_eq!(
source_map.cache.get(&file_id1).unwrap().contents,
initial_contents
);
let cache_key = (
mount_name.to_string(),
relative_path.to_str().unwrap().to_string(),
);
assert!(source_map.file_cache.get(&cache_key).is_some());
assert_eq!(*source_map.file_cache.get(&cache_key).unwrap(), file_id1);
let file_id2 = source_map.set(mount_name, relative_path, updated_contents);
assert_eq!(file_id1, file_id2);
assert_eq!(
source_map.cache.get(&file_id2).unwrap().contents,
updated_contents
);
assert_eq!(*source_map.file_cache.get(&cache_key).unwrap(), file_id2);
let different_path = Path::new("different_file.txt");
let different_contents = "different content";
let file_id3 = source_map.set(mount_name, different_path, different_contents);
assert_ne!(file_id1, file_id3);
assert!(source_map.cache.get(&file_id3).is_some());
let different_cache_key = (
mount_name.to_string(),
different_path.to_str().unwrap().to_string(),
);
assert_eq!(
*source_map.file_cache.get(&different_cache_key).unwrap(),
file_id3
);
assert_eq!(*source_map.file_cache.get(&cache_key).unwrap(), file_id1);
}
#[test]
fn test_multibyte_utf8_char_boundaries() {
let mut source_map = create_test_source_map();
let file_content = "Hello\u{a0}World\nSecond line with emoji 😀\n";
let file_id = 1;
source_map.add_manual(file_id, "test", &PathBuf::from("utf8.txt"), file_content);
assert_eq!(source_map.get_span_location_utf8(file_id, 0), Some((1, 1))); assert_eq!(source_map.get_span_location_utf8(file_id, 5), Some((1, 6))); assert_eq!(source_map.get_span_location_utf8(file_id, 6), None); assert_eq!(source_map.get_span_location_utf8(file_id, 7), Some((1, 7)));
let span1 = Span {
file_id,
offset: 0,
length: 7,
};
let text = source_map.get_text_span(&span1).unwrap();
assert_eq!(text, "Hello\u{a0}");
let span2 = Span {
file_id,
offset: 6, length: 5,
};
assert_eq!(source_map.get_text_span(&span2), None); }