aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/test_utils.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2021-02-17 14:53:31 +0000
committerAleksey Kladov <[email protected]>2021-02-17 14:53:31 +0000
commit3db64a400c78bbd2708e67ddc07df1001fff3f29 (patch)
tree5386aab9c452981be09bc3e4362643a34e6e3617 /crates/ide_completion/src/test_utils.rs
parent6334ce866ab095215381c4b72692b20a84d26e96 (diff)
rename completion -> ide_completion
We don't have completion-related PRs in flight, so lets do it
Diffstat (limited to 'crates/ide_completion/src/test_utils.rs')
-rw-r--r--crates/ide_completion/src/test_utils.rs153
1 files changed, 153 insertions, 0 deletions
diff --git a/crates/ide_completion/src/test_utils.rs b/crates/ide_completion/src/test_utils.rs
new file mode 100644
index 000000000..baff83305
--- /dev/null
+++ b/crates/ide_completion/src/test_utils.rs
@@ -0,0 +1,153 @@
1//! Runs completion for testing purposes.
2
3use hir::{PrefixKind, Semantics};
4use ide_db::{
5 base_db::{fixture::ChangeFixture, FileLoader, FilePosition},
6 helpers::{
7 insert_use::{InsertUseConfig, MergeBehavior},
8 SnippetCap,
9 },
10 RootDatabase,
11};
12use itertools::Itertools;
13use stdx::{format_to, trim_indent};
14use syntax::{AstNode, NodeOrToken, SyntaxElement};
15use test_utils::{assert_eq_text, RangeOrOffset};
16
17use crate::{item::CompletionKind, CompletionConfig, CompletionItem};
18
19pub(crate) const TEST_CONFIG: CompletionConfig = CompletionConfig {
20 enable_postfix_completions: true,
21 enable_imports_on_the_fly: true,
22 add_call_parenthesis: true,
23 add_call_argument_snippets: true,
24 snippet_cap: SnippetCap::new(true),
25 insert_use: InsertUseConfig {
26 merge: Some(MergeBehavior::Full),
27 prefix_kind: PrefixKind::Plain,
28 },
29};
30
31/// Creates analysis from a multi-file fixture, returns positions marked with $0.
32pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) {
33 let change_fixture = ChangeFixture::parse(ra_fixture);
34 let mut database = RootDatabase::default();
35 database.apply_change(change_fixture.change);
36 let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)");
37 let offset = match range_or_offset {
38 RangeOrOffset::Range(_) => panic!(),
39 RangeOrOffset::Offset(it) => it,
40 };
41 (database, FilePosition { file_id, offset })
42}
43
44pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec<CompletionItem> {
45 do_completion_with_config(TEST_CONFIG, code, kind)
46}
47
48pub(crate) fn do_completion_with_config(
49 config: CompletionConfig,
50 code: &str,
51 kind: CompletionKind,
52) -> Vec<CompletionItem> {
53 let mut kind_completions: Vec<CompletionItem> =
54 get_all_items(config, code).into_iter().filter(|c| c.completion_kind == kind).collect();
55 kind_completions.sort_by(|l, r| l.label().cmp(r.label()));
56 kind_completions
57}
58
59pub(crate) fn completion_list(code: &str, kind: CompletionKind) -> String {
60 completion_list_with_config(TEST_CONFIG, code, kind)
61}
62
63pub(crate) fn completion_list_with_config(
64 config: CompletionConfig,
65 code: &str,
66 kind: CompletionKind,
67) -> String {
68 let kind_completions: Vec<CompletionItem> =
69 get_all_items(config, code).into_iter().filter(|c| c.completion_kind == kind).collect();
70 let label_width = kind_completions
71 .iter()
72 .map(|it| monospace_width(it.label()))
73 .max()
74 .unwrap_or_default()
75 .min(16);
76 kind_completions
77 .into_iter()
78 .map(|it| {
79 let tag = it.kind().unwrap().tag();
80 let var_name = format!("{} {}", tag, it.label());
81 let mut buf = var_name;
82 if let Some(detail) = it.detail() {
83 let width = label_width.saturating_sub(monospace_width(it.label()));
84 format_to!(buf, "{:width$} {}", "", detail, width = width);
85 }
86 if it.deprecated() {
87 format_to!(buf, " DEPRECATED");
88 }
89 format_to!(buf, "\n");
90 buf
91 })
92 .collect()
93}
94
95fn monospace_width(s: &str) -> usize {
96 s.chars().count()
97}
98
99pub(crate) fn check_edit(what: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
100 check_edit_with_config(TEST_CONFIG, what, ra_fixture_before, ra_fixture_after)
101}
102
103pub(crate) fn check_edit_with_config(
104 config: CompletionConfig,
105 what: &str,
106 ra_fixture_before: &str,
107 ra_fixture_after: &str,
108) {
109 let ra_fixture_after = trim_indent(ra_fixture_after);
110 let (db, position) = position(ra_fixture_before);
111 let completions: Vec<CompletionItem> =
112 crate::completions(&db, &config, position).unwrap().into();
113 let (completion,) = completions
114 .iter()
115 .filter(|it| it.lookup() == what)
116 .collect_tuple()
117 .unwrap_or_else(|| panic!("can't find {:?} completion in {:#?}", what, completions));
118 let mut actual = db.file_text(position.file_id).to_string();
119
120 let mut combined_edit = completion.text_edit().to_owned();
121 if let Some(import_text_edit) =
122 completion.import_to_add().and_then(|edit| edit.to_text_edit(config.insert_use.merge))
123 {
124 combined_edit.union(import_text_edit).expect(
125 "Failed to apply completion resolve changes: change ranges overlap, but should not",
126 )
127 }
128
129 combined_edit.apply(&mut actual);
130 assert_eq_text!(&ra_fixture_after, &actual)
131}
132
133pub(crate) fn check_pattern_is_applicable(code: &str, check: fn(SyntaxElement) -> bool) {
134 let (db, pos) = position(code);
135
136 let sema = Semantics::new(&db);
137 let original_file = sema.parse(pos.file_id);
138 let token = original_file.syntax().token_at_offset(pos.offset).left_biased().unwrap();
139 assert!(check(NodeOrToken::Token(token)));
140}
141
142pub(crate) fn check_pattern_is_not_applicable(code: &str, check: fn(SyntaxElement) -> bool) {
143 let (db, pos) = position(code);
144 let sema = Semantics::new(&db);
145 let original_file = sema.parse(pos.file_id);
146 let token = original_file.syntax().token_at_offset(pos.offset).left_biased().unwrap();
147 assert!(!check(NodeOrToken::Token(token)));
148}
149
150pub(crate) fn get_all_items(config: CompletionConfig, code: &str) -> Vec<CompletionItem> {
151 let (db, position) = position(code);
152 crate::completions(&db, &config, position).unwrap().into()
153}