Rewrite snapshot checks

This commit is contained in:
Mikhail Rakhmanov 2020-06-12 20:30:57 +02:00
parent 42a719ad25
commit 3576671043
4 changed files with 100 additions and 245 deletions

View File

@ -61,7 +61,6 @@ fn add_keyword(
pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) {
add_keyword(ctx, acc, "fn", "fn $0() {}", ctx.is_new_item || ctx.block_expr_parent);
add_keyword(ctx, acc, "type", "type ", ctx.is_new_item || ctx.block_expr_parent);
add_keyword(ctx, acc, "use", "fn $0() {}", ctx.is_new_item || ctx.block_expr_parent);
add_keyword(ctx, acc, "impl", "impl $0 {}", ctx.is_new_item);
add_keyword(ctx, acc, "trait", "impl $0 {}", ctx.is_new_item);
@ -111,12 +110,9 @@ fn complete_return(
#[cfg(test)]
mod tests {
use crate::{
completion::{
test_utils::{do_completion, do_completion_with_position},
CompletionItem, CompletionKind,
},
CompletionItemKind,
use crate::completion::{
test_utils::{do_completion, get_completions},
CompletionItem, CompletionKind,
};
use insta::assert_debug_snapshot;
@ -124,132 +120,39 @@ mod tests {
do_completion(code, CompletionKind::Keyword)
}
fn get_completion_text_and_assert_positions(code: &str) -> Vec<(String, String)> {
let (position, completion_items) =
do_completion_with_position(code, CompletionKind::Keyword);
let mut returned_keywords = Vec::<(String, String)>::new();
for item in completion_items {
assert!(item.text_edit().len() == 1);
assert!(item.kind() == Some(CompletionItemKind::Keyword));
let atom = item.text_edit().iter().next().unwrap().clone();
assert!(atom.delete.start() == position.offset);
assert!(atom.delete.end() == position.offset);
let pair = (item.label().to_string(), atom.insert);
returned_keywords.push(pair);
}
returned_keywords.sort();
returned_keywords
}
#[test]
fn completes_keywords_in_use_stmt_new_approach() {
assert_debug_snapshot!(
get_completion_text_and_assert_positions(r"
use <|>
"),
@r###"
[
(
"crate",
"crate::",
),
(
"self",
"self",
),
(
"super",
"super::",
),
]
"###
);
fn get_keyword_completions(code: &str) -> Vec<String> {
get_completions(code, CompletionKind::Keyword)
}
#[test]
fn completes_keywords_in_use_stmt() {
assert_debug_snapshot!(
do_keyword_completion(
r"
use <|>
",
),
get_keyword_completions(r"use <|>"),
@r###"
[
CompletionItem {
label: "crate",
source_range: 21..21,
delete: 21..21,
insert: "crate::",
kind: Keyword,
},
CompletionItem {
label: "self",
source_range: 21..21,
delete: 21..21,
insert: "self",
kind: Keyword,
},
CompletionItem {
label: "super",
source_range: 21..21,
delete: 21..21,
insert: "super::",
kind: Keyword,
},
"kw crate",
"kw self",
"kw super",
]
"###
);
assert_debug_snapshot!(
do_keyword_completion(
r"
use a::<|>
",
),
get_keyword_completions(r"use a::<|>"),
@r###"
[
CompletionItem {
label: "self",
source_range: 24..24,
delete: 24..24,
insert: "self",
kind: Keyword,
},
CompletionItem {
label: "super",
source_range: 24..24,
delete: 24..24,
insert: "super::",
kind: Keyword,
},
"kw self",
"kw super",
]
"###
);
assert_debug_snapshot!(
do_keyword_completion(
r"
use a::{b, <|>}
",
),
get_keyword_completions(r"use a::{b, <|>}"),
@r###"
[
CompletionItem {
label: "self",
source_range: 28..28,
delete: 28..28,
insert: "self",
kind: Keyword,
},
CompletionItem {
label: "super",
source_range: 28..28,
delete: 28..28,
insert: "super::",
kind: Keyword,
},
"kw self",
"kw super",
]
"###
);
@ -258,50 +161,22 @@ mod tests {
#[test]
fn completes_various_keywords_in_function() {
assert_debug_snapshot!(
do_keyword_completion(
r"
fn quux() {
<|>
}
",
),
get_keyword_completions(r"fn quux() { <|> }"),
@r###"
[
CompletionItem {
label: "if",
source_range: 49..49,
delete: 49..49,
insert: "if $0 {}",
kind: Keyword,
},
CompletionItem {
label: "loop",
source_range: 49..49,
delete: 49..49,
insert: "loop {$0}",
kind: Keyword,
},
CompletionItem {
label: "match",
source_range: 49..49,
delete: 49..49,
insert: "match $0 {}",
kind: Keyword,
},
CompletionItem {
label: "return",
source_range: 49..49,
delete: 49..49,
insert: "return;",
kind: Keyword,
},
CompletionItem {
label: "while",
source_range: 49..49,
delete: 49..49,
insert: "while $0 {}",
kind: Keyword,
},
"kw const",
"kw extern",
"kw fn",
"kw let",
"kw loop",
"kw match",
"kw mod",
"kw return",
"kw static",
"kw type",
"kw unsafe",
"kw use",
"kw while",
]
"###
);

View File

@ -125,6 +125,32 @@ pub enum CompletionItemKind {
Attribute,
}
impl CompletionItemKind {
pub fn tag(&self) -> String {
let tag = match self {
CompletionItemKind::Snippet => "sn",
CompletionItemKind::Keyword => "kw",
CompletionItemKind::Module => "md",
CompletionItemKind::Function => "fn",
CompletionItemKind::BuiltinType => "bt",
CompletionItemKind::Struct => "st",
CompletionItemKind::Enum => "en",
CompletionItemKind::EnumVariant => "ev",
CompletionItemKind::Binding => "bn",
CompletionItemKind::Field => "fd",
CompletionItemKind::Static => "sc",
CompletionItemKind::Const => "ct",
CompletionItemKind::Trait => "tt",
CompletionItemKind::TypeAlias => "ta",
CompletionItemKind::Method => "me",
CompletionItemKind::TypeParam => "tp",
CompletionItemKind::Macro => "ma",
CompletionItemKind::Attribute => "at",
};
tag.to_owned()
}
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub(crate) enum CompletionKind {
/// Parser-based keyword completion.

View File

@ -121,115 +121,51 @@ mod tests {
#[test]
fn test_unsafe_is_prev() {
check_pattern_is_applicable(
r"
unsafe i<|>
",
unsafe_is_prev,
);
check_pattern_is_applicable(r"unsafe i<|>", unsafe_is_prev);
}
#[test]
fn test_if_is_prev() {
check_pattern_is_applicable(
r"
if l<|>
",
if_is_prev,
);
check_pattern_is_applicable(r"if l<|>", if_is_prev);
}
#[test]
fn test_inside_trait() {
check_pattern_is_applicable(
r"
trait A {
fn<|>
}
",
inside_trait,
);
check_pattern_is_applicable(r"trait A { fn<|> }", inside_trait);
}
#[test]
fn test_has_trait_as_prev_sibling() {
check_pattern_is_applicable(
r"
trait A w<|> {
}
",
has_trait_as_prev_sibling,
);
check_pattern_is_applicable(r"trait A w<|> {}", has_trait_as_prev_sibling);
}
#[test]
fn test_has_impl_as_prev_sibling() {
check_pattern_is_applicable(
r"
impl A w<|> {
}
",
has_impl_as_prev_sibling,
);
check_pattern_is_applicable(r"impl A w<|> {}", has_impl_as_prev_sibling);
}
#[test]
fn test_parent_block_expr() {
check_pattern_is_applicable(
r"
fn my_fn() {
let a = 2;
f<|>
}
",
has_block_expr_parent,
);
check_pattern_is_applicable(r"fn my_fn() { let a = 2; f<|> }", has_block_expr_parent);
}
#[test]
fn test_has_ref_pat_parent_in_func_parameters() {
check_pattern_is_applicable(
r"
fn my_fn(&<|>) {
let a = 2;
}
",
has_ref_pat_parent,
);
check_pattern_is_applicable(r"fn my_fn(&<|>) {}", has_ref_pat_parent);
}
#[test]
fn test_has_ref_pat_parent_in_let_statement() {
check_pattern_is_applicable(
r"
fn my_fn() {
let &<|>
}
",
has_ref_pat_parent,
);
check_pattern_is_applicable(r"fn my_fn() { let &<|> }", has_ref_pat_parent);
}
#[test]
fn test_has_bind_pat_parent_in_func_parameters() {
check_pattern_is_applicable(
r"
fn my_fn(m<|>) {
}
",
has_bind_pat_parent,
);
check_pattern_is_applicable(r"fn my_fn(m<|>) {}", has_bind_pat_parent);
}
#[test]
fn test_has_bind_pat_parent_in_let_statement() {
check_pattern_is_applicable(
r"
fn my_fn() {
let m<|>
}
",
has_bind_pat_parent,
);
check_pattern_is_applicable(r"fn my_fn() { let m<|> }", has_bind_pat_parent);
}
}

View File

@ -3,7 +3,7 @@
use crate::{
completion::{completion_item::CompletionKind, CompletionConfig},
mock_analysis::{analysis_and_position, single_file_with_position},
CompletionItem, FilePosition,
CompletionItem,
};
use hir::Semantics;
use ra_syntax::{AstNode, NodeOrToken, SyntaxElement};
@ -12,11 +12,8 @@ pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec<CompletionI
do_completion_with_options(code, kind, &CompletionConfig::default())
}
pub(crate) fn do_completion_with_position(
code: &str,
kind: CompletionKind,
) -> (FilePosition, Vec<CompletionItem>) {
do_completion_with_options_and_position(code, kind, &CompletionConfig::default())
pub(crate) fn get_completions(code: &str, kind: CompletionKind) -> Vec<String> {
get_completions_with_options(code, kind, &CompletionConfig::default())
}
pub(crate) fn do_completion_with_options(
@ -24,25 +21,46 @@ pub(crate) fn do_completion_with_options(
kind: CompletionKind,
options: &CompletionConfig,
) -> Vec<CompletionItem> {
do_completion_with_options_and_position(code, kind, options).1
let mut kind_completions: Vec<CompletionItem> = get_all_completion_items(code, options)
.into_iter()
.filter(|c| c.completion_kind == kind)
.collect();
kind_completions.sort_by_key(|c| c.label().to_owned());
kind_completions
}
pub(crate) fn do_completion_with_options_and_position(
code: &str,
kind: CompletionKind,
options: &CompletionConfig,
) -> (FilePosition, Vec<CompletionItem>) {
fn get_all_completion_items(code: &str, options: &CompletionConfig) -> Vec<CompletionItem> {
let (analysis, position) = if code.contains("//-") {
analysis_and_position(code)
} else {
single_file_with_position(code)
};
let completions = analysis.completions(options, position).unwrap().unwrap();
let completion_items: Vec<CompletionItem> = completions.into();
let mut kind_completions: Vec<CompletionItem> =
completion_items.into_iter().filter(|c| c.completion_kind == kind).collect();
analysis.completions(options, position).unwrap().unwrap().into()
}
pub(crate) fn get_all_completions(code: &str, options: &CompletionConfig) -> Vec<String> {
let mut kind_completions = get_all_completion_items(code, options);
kind_completions.sort_by_key(|c| c.label().to_owned());
(position, kind_completions)
kind_completions
.into_iter()
.map(|it| format!("{} {}", it.kind().unwrap().tag(), it.label()))
.collect()
}
pub(crate) fn get_completions_with_options(
code: &str,
kind: CompletionKind,
options: &CompletionConfig,
) -> Vec<String> {
let mut kind_completions: Vec<CompletionItem> = get_all_completion_items(code, options)
.into_iter()
.filter(|c| c.completion_kind == kind)
.collect();
kind_completions.sort_by_key(|c| c.label().to_owned());
kind_completions
.into_iter()
.map(|it| format!("{} {}", it.kind().unwrap().tag(), it.label()))
.collect()
}
pub(crate) fn check_pattern_is_applicable(code: &str, check: fn(SyntaxElement) -> bool) {