Skip to content

Commit a2b4385

Browse files
committed
Add few smoke tests for patterns and refactoring
1 parent f46bc12 commit a2b4385

File tree

4 files changed

+111
-10
lines changed

4 files changed

+111
-10
lines changed

crates/ra_ide/src/completion/complete_keyword.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,13 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
6565
add_keyword(ctx, acc, "use", "fn $0() {}", ctx.is_new_item || ctx.block_expr_parent);
6666
add_keyword(ctx, acc, "impl", "impl $0 {}", ctx.is_new_item);
6767
add_keyword(ctx, acc, "trait", "impl $0 {}", ctx.is_new_item);
68-
add_keyword(ctx, acc, "enum", "enum $0 {}", ctx.is_new_item && !ctx.after_unsafe);
69-
add_keyword(ctx, acc, "struct", "struct $0 {}", ctx.is_new_item && !ctx.after_unsafe);
70-
add_keyword(ctx, acc, "union", "union $0 {}", ctx.is_new_item && !ctx.after_unsafe);
68+
add_keyword(ctx, acc, "enum", "enum $0 {}", ctx.is_new_item && !ctx.unsafe_is_prev);
69+
add_keyword(ctx, acc, "struct", "struct $0 {}", ctx.is_new_item && !ctx.unsafe_is_prev);
70+
add_keyword(ctx, acc, "union", "union $0 {}", ctx.is_new_item && !ctx.unsafe_is_prev);
7171
add_keyword(ctx, acc, "match", "match $0 {}", ctx.block_expr_parent);
7272
add_keyword(ctx, acc, "loop", "loop {$0}", ctx.block_expr_parent);
7373
add_keyword(ctx, acc, "while", "while $0 {}", ctx.block_expr_parent);
74-
add_keyword(ctx, acc, "let", "let ", ctx.after_if || ctx.block_expr_parent);
74+
add_keyword(ctx, acc, "let", "let ", ctx.if_is_prev || ctx.block_expr_parent);
7575
add_keyword(ctx, acc, "else", "else {$0}", ctx.after_if);
7676
add_keyword(ctx, acc, "else if", "else if $0 {}", ctx.after_if);
7777
add_keyword(ctx, acc, "mod", "mod $0 {}", ctx.is_new_item || ctx.block_expr_parent);

crates/ra_ide/src/completion/completion_context.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use ra_syntax::{
1212
use ra_text_edit::Indel;
1313

1414
use super::patterns::{
15-
goes_after_unsafe, has_bind_pat_parent, has_block_expr_parent, has_impl_as_prev_sibling,
16-
has_ref_pat_parent, has_trait_as_prev_sibling, inside_trait, is_in_loop_body,
15+
has_bind_pat_parent, has_block_expr_parent, has_impl_as_prev_sibling, has_ref_pat_parent,
16+
has_trait_as_prev_sibling, if_is_prev, inside_trait, is_in_loop_body, unsafe_is_prev,
1717
};
1818
use crate::{call_info::ActiveParameter, completion::CompletionConfig, FilePosition};
1919
use test_utils::mark;
@@ -64,7 +64,8 @@ pub(crate) struct CompletionContext<'a> {
6464
pub(super) is_path_type: bool,
6565
pub(super) has_type_args: bool,
6666
pub(super) attribute_under_caret: Option<ast::Attr>,
67-
pub(super) after_unsafe: bool,
67+
pub(super) unsafe_is_prev: bool,
68+
pub(super) if_is_prev: bool,
6869
pub(super) block_expr_parent: bool,
6970
pub(super) bind_pat_parent: bool,
7071
pub(super) ref_pat_parent: bool,
@@ -130,14 +131,15 @@ impl<'a> CompletionContext<'a> {
130131
has_type_args: false,
131132
dot_receiver_is_ambiguous_float_literal: false,
132133
attribute_under_caret: None,
133-
after_unsafe: false,
134+
unsafe_is_prev: false,
134135
in_loop_body: false,
135136
ref_pat_parent: false,
136137
bind_pat_parent: false,
137138
block_expr_parent: false,
138139
inside_trait: false,
139140
trait_as_prev_sibling: false,
140141
impl_as_prev_sibling: false,
142+
if_is_prev: false,
141143
};
142144

143145
let mut original_file = original_file.syntax().clone();
@@ -212,7 +214,8 @@ impl<'a> CompletionContext<'a> {
212214
let fake_ident_token = file_with_fake_ident.token_at_offset(offset).right_biased().unwrap();
213215
let syntax_element = NodeOrToken::Token(fake_ident_token.clone());
214216
self.block_expr_parent = has_block_expr_parent(syntax_element.clone());
215-
self.after_unsafe = goes_after_unsafe(syntax_element.clone());
217+
self.unsafe_is_prev = unsafe_is_prev(syntax_element.clone());
218+
self.if_is_prev = if_is_prev(syntax_element.clone());
216219
self.bind_pat_parent = has_bind_pat_parent(syntax_element.clone());
217220
self.ref_pat_parent = has_ref_pat_parent(syntax_element.clone());
218221
self.in_loop_body = is_in_loop_body(syntax_element.clone());

crates/ra_ide/src/completion/patterns.rs

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,22 @@ pub(crate) fn has_ref_pat_parent(element: SyntaxElement) -> bool {
2222
element.ancestors().find(|it| it.kind() == REF_PAT).is_some()
2323
}
2424

25-
pub(crate) fn goes_after_unsafe(element: SyntaxElement) -> bool {
25+
pub(crate) fn unsafe_is_prev(element: SyntaxElement) -> bool {
2626
element
2727
.into_token()
2828
.and_then(|it| previous_non_trivia_token(it))
2929
.filter(|it| it.kind() == UNSAFE_KW)
3030
.is_some()
3131
}
3232

33+
pub(crate) fn if_is_prev(element: SyntaxElement) -> bool {
34+
element
35+
.into_token()
36+
.and_then(|it| previous_non_trivia_token(it))
37+
.filter(|it| it.kind() == IF_KW)
38+
.is_some()
39+
}
40+
3341
pub(crate) fn has_block_expr_parent(element: SyntaxElement) -> bool {
3442
not_same_range_ancestor(element).filter(|it| it.kind() == BLOCK_EXPR).is_some()
3543
}
@@ -110,3 +118,79 @@ fn previous_sibling_or_ancestor_sibling(element: SyntaxElement) -> Option<Syntax
110118
non_trivia_sibling(NodeOrToken::Node(prev_sibling_node), Direction::Prev)
111119
}
112120
}
121+
122+
#[cfg(test)]
123+
mod tests {
124+
use super::{
125+
has_block_expr_parent, has_impl_as_prev_sibling, has_trait_as_prev_sibling, if_is_prev,
126+
inside_trait, unsafe_is_prev,
127+
};
128+
use crate::completion::test_utils::check_pattern_is_applicable;
129+
130+
#[test]
131+
fn test_unsafe_is_prev() {
132+
check_pattern_is_applicable(
133+
r"
134+
unsafe i<|>
135+
",
136+
unsafe_is_prev,
137+
);
138+
}
139+
140+
#[test]
141+
fn test_if_is_prev() {
142+
check_pattern_is_applicable(
143+
r"
144+
if l<|>
145+
",
146+
if_is_prev,
147+
);
148+
}
149+
150+
#[test]
151+
fn test_inside_trait() {
152+
check_pattern_is_applicable(
153+
r"
154+
trait A {
155+
fn<|>
156+
}
157+
",
158+
inside_trait,
159+
);
160+
}
161+
162+
#[test]
163+
fn test_has_trait_as_prev_sibling() {
164+
check_pattern_is_applicable(
165+
r"
166+
trait A w<|> {
167+
}
168+
",
169+
has_trait_as_prev_sibling,
170+
);
171+
}
172+
173+
#[test]
174+
fn test_has_impl_as_prev_sibling() {
175+
check_pattern_is_applicable(
176+
r"
177+
impl A w<|> {
178+
}
179+
",
180+
has_impl_as_prev_sibling,
181+
);
182+
}
183+
184+
#[test]
185+
fn test_parent_block_expr() {
186+
check_pattern_is_applicable(
187+
r"
188+
fn my_fn() {
189+
let a = 2;
190+
f<|>
191+
}
192+
",
193+
has_block_expr_parent,
194+
);
195+
}
196+
}

crates/ra_ide/src/completion/test_utils.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use crate::{
55
mock_analysis::{analysis_and_position, single_file_with_position},
66
CompletionItem,
77
};
8+
use hir::Semantics;
9+
use ra_syntax::{AstNode, NodeOrToken, SyntaxElement, SyntaxToken};
810

911
pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec<CompletionItem> {
1012
do_completion_with_options(code, kind, &CompletionConfig::default())
@@ -27,3 +29,15 @@ pub(crate) fn do_completion_with_options(
2729
kind_completions.sort_by_key(|c| c.label().to_owned());
2830
kind_completions
2931
}
32+
33+
pub(crate) fn check_pattern_is_applicable(code: &str, check: fn(SyntaxElement) -> bool) {
34+
let (analysis, pos) = single_file_with_position(code);
35+
analysis
36+
.with_db(|db| {
37+
let sema = Semantics::new(db);
38+
let original_file = sema.parse(pos.file_id);
39+
let token = original_file.syntax().token_at_offset(pos.offset).left_biased().unwrap();
40+
assert!(check(NodeOrToken::Token(token)));
41+
})
42+
.unwrap();
43+
}

0 commit comments

Comments
 (0)