rust-analyzer/crates/ra_ide_api/tests/test/main.rs
Ville Penttinen ac52d9a1f1 Add optional range parameter to SyntaxTreeParams
When range is provided, instead of showing the syntax for the whole file, we'll
show the syntax tree for the given range.
2019-03-03 19:49:50 +02:00

274 lines
6 KiB
Rust

use insta::assert_debug_snapshot_matches;
use ra_ide_api::{
mock_analysis::{single_file, single_file_with_position, single_file_with_range, MockAnalysis},
AnalysisChange, CrateGraph, Edition::Edition2018, Query, NavigationTarget,
ReferenceSearchResult,
};
use ra_syntax::SmolStr;
#[test]
fn test_unresolved_module_diagnostic() {
let (analysis, file_id) = single_file("mod foo;");
let diagnostics = analysis.diagnostics(file_id).unwrap();
assert_debug_snapshot_matches!("unresolved_module_diagnostic", &diagnostics);
}
// FIXME: move this test to hir
#[test]
fn test_unresolved_module_diagnostic_no_diag_for_inline_mode() {
let (analysis, file_id) = single_file("mod foo {}");
let diagnostics = analysis.diagnostics(file_id).unwrap();
assert!(diagnostics.is_empty());
}
#[test]
fn test_resolve_crate_root() {
let mock = MockAnalysis::with_files(
"
//- /bar.rs
mod foo;
//- /foo.rs
// empty <|>
",
);
let root_file = mock.id_of("/bar.rs");
let mod_file = mock.id_of("/foo.rs");
let mut host = mock.analysis_host();
assert!(host.analysis().crate_for(mod_file).unwrap().is_empty());
let mut crate_graph = CrateGraph::default();
let crate_id = crate_graph.add_crate_root(root_file, Edition2018);
let mut change = AnalysisChange::new();
change.set_crate_graph(crate_graph);
host.apply_change(change);
assert_eq!(host.analysis().crate_for(mod_file).unwrap(), vec![crate_id]);
}
fn get_all_refs(text: &str) -> ReferenceSearchResult {
let (analysis, position) = single_file_with_position(text);
analysis.find_all_refs(position).unwrap().unwrap()
}
fn get_symbols_matching(text: &str, query: &str) -> Vec<NavigationTarget> {
let (analysis, _) = single_file(text);
analysis.symbol_search(Query::new(query.into())).unwrap()
}
#[test]
fn test_find_all_refs_for_local() {
let code = r#"
fn main() {
let mut i = 1;
let j = 1;
i = i<|> + j;
{
i = 0;
}
i = 5;
}"#;
let refs = get_all_refs(code);
assert_eq!(refs.len(), 5);
}
#[test]
fn test_find_all_refs_for_param_inside() {
let code = r#"
fn foo(i : u32) -> u32 {
i<|>
}"#;
let refs = get_all_refs(code);
assert_eq!(refs.len(), 2);
}
#[test]
fn test_find_all_refs_for_fn_param() {
let code = r#"
fn foo(i<|> : u32) -> u32 {
i
}"#;
let refs = get_all_refs(code);
assert_eq!(refs.len(), 2);
}
#[test]
fn test_world_symbols_with_no_container() {
let code = r#"
enum FooInner { }
"#;
let mut symbols = get_symbols_matching(code, "FooInner");
let s = symbols.pop().unwrap();
assert_eq!(s.name(), "FooInner");
assert!(s.container_name().is_none());
}
#[test]
fn test_world_symbols_include_container_name() {
let code = r#"
fn foo() {
enum FooInner { }
}
"#;
let mut symbols = get_symbols_matching(code, "FooInner");
let s = symbols.pop().unwrap();
assert_eq!(s.name(), "FooInner");
assert_eq!(s.container_name(), Some(&SmolStr::new("foo")));
let code = r#"
mod foo {
struct FooInner;
}
"#;
let mut symbols = get_symbols_matching(code, "FooInner");
let s = symbols.pop().unwrap();
assert_eq!(s.name(), "FooInner");
assert_eq!(s.container_name(), Some(&SmolStr::new("foo")));
}
#[test]
fn test_syntax_tree_without_range() {
// Basic syntax
let (analysis, file_id) = single_file(r#"fn foo() {}"#);
let syn = analysis.syntax_tree(file_id, None);
assert_eq!(
syn.trim(),
r#"
SOURCE_FILE@[0; 11)
FN_DEF@[0; 11)
FN_KW@[0; 2)
WHITESPACE@[2; 3)
NAME@[3; 6)
IDENT@[3; 6) "foo"
PARAM_LIST@[6; 8)
L_PAREN@[6; 7)
R_PAREN@[7; 8)
WHITESPACE@[8; 9)
BLOCK@[9; 11)
L_CURLY@[9; 10)
R_CURLY@[10; 11)
"#
.trim()
);
let (analysis, file_id) = single_file(
r#"
fn test() {
assert!("
fn foo() {
}
", "");
}"#
.trim(),
);
let syn = analysis.syntax_tree(file_id, None);
assert_eq!(
syn.trim(),
r#"
SOURCE_FILE@[0; 60)
FN_DEF@[0; 60)
FN_KW@[0; 2)
WHITESPACE@[2; 3)
NAME@[3; 7)
IDENT@[3; 7) "test"
PARAM_LIST@[7; 9)
L_PAREN@[7; 8)
R_PAREN@[8; 9)
WHITESPACE@[9; 10)
BLOCK@[10; 60)
L_CURLY@[10; 11)
WHITESPACE@[11; 16)
EXPR_STMT@[16; 58)
MACRO_CALL@[16; 57)
PATH@[16; 22)
PATH_SEGMENT@[16; 22)
NAME_REF@[16; 22)
IDENT@[16; 22) "assert"
EXCL@[22; 23)
TOKEN_TREE@[23; 57)
L_PAREN@[23; 24)
STRING@[24; 52)
COMMA@[52; 53)
WHITESPACE@[53; 54)
STRING@[54; 56)
R_PAREN@[56; 57)
SEMI@[57; 58)
WHITESPACE@[58; 59)
R_CURLY@[59; 60)
"#
.trim()
);
}
#[test]
fn test_syntax_tree_with_range() {
let (analysis, range) = single_file_with_range(r#"<|>fn foo() {}<|>"#.trim());
let syn = analysis.syntax_tree(range.file_id, Some(range.range));
assert_eq!(
syn.trim(),
r#"
FN_DEF@[0; 11)
FN_KW@[0; 2)
WHITESPACE@[2; 3)
NAME@[3; 6)
IDENT@[3; 6) "foo"
PARAM_LIST@[6; 8)
L_PAREN@[6; 7)
R_PAREN@[7; 8)
WHITESPACE@[8; 9)
BLOCK@[9; 11)
L_CURLY@[9; 10)
R_CURLY@[10; 11)
"#
.trim()
);
let (analysis, range) = single_file_with_range(
r#"fn test() {
<|>assert!("
fn foo() {
}
", "");<|>
}"#
.trim(),
);
let syn = analysis.syntax_tree(range.file_id, Some(range.range));
assert_eq!(
syn.trim(),
r#"
EXPR_STMT@[16; 58)
MACRO_CALL@[16; 57)
PATH@[16; 22)
PATH_SEGMENT@[16; 22)
NAME_REF@[16; 22)
IDENT@[16; 22) "assert"
EXCL@[22; 23)
TOKEN_TREE@[23; 57)
L_PAREN@[23; 24)
STRING@[24; 52)
COMMA@[52; 53)
WHITESPACE@[53; 54)
STRING@[54; 56)
R_PAREN@[56; 57)
SEMI@[57; 58)
"#
.trim()
);
}