diff options
Diffstat (limited to 'crates/ide_db/src/traits')
-rw-r--r-- | crates/ide_db/src/traits/tests.rs | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/crates/ide_db/src/traits/tests.rs b/crates/ide_db/src/traits/tests.rs new file mode 100644 index 000000000..09c7ac3ec --- /dev/null +++ b/crates/ide_db/src/traits/tests.rs | |||
@@ -0,0 +1,144 @@ | |||
1 | use crate::RootDatabase; | ||
2 | use base_db::{fixture::ChangeFixture, FilePosition}; | ||
3 | use expect_test::{expect, Expect}; | ||
4 | use hir::Semantics; | ||
5 | use syntax::ast::{self, AstNode}; | ||
6 | use test_utils::RangeOrOffset; | ||
7 | |||
8 | /// Creates analysis from a multi-file fixture, returns positions marked with <|>. | ||
9 | pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) { | ||
10 | let change_fixture = ChangeFixture::parse(ra_fixture); | ||
11 | let mut database = RootDatabase::default(); | ||
12 | database.apply_change(change_fixture.change); | ||
13 | let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker (<|>)"); | ||
14 | let offset = match range_or_offset { | ||
15 | RangeOrOffset::Range(_) => panic!(), | ||
16 | RangeOrOffset::Offset(it) => it, | ||
17 | }; | ||
18 | (database, FilePosition { file_id, offset }) | ||
19 | } | ||
20 | |||
21 | fn check_trait(ra_fixture: &str, expect: Expect) { | ||
22 | let (db, position) = position(ra_fixture); | ||
23 | let sema = Semantics::new(&db); | ||
24 | let file = sema.parse(position.file_id); | ||
25 | let impl_block: ast::Impl = | ||
26 | sema.find_node_at_offset_with_descend(file.syntax(), position.offset).unwrap(); | ||
27 | let trait_ = crate::traits::resolve_target_trait(&sema, &impl_block); | ||
28 | let actual = match trait_ { | ||
29 | Some(trait_) => trait_.name(&db).to_string(), | ||
30 | None => String::new(), | ||
31 | }; | ||
32 | expect.assert_eq(&actual); | ||
33 | } | ||
34 | |||
35 | fn check_missing_assoc(ra_fixture: &str, expect: Expect) { | ||
36 | let (db, position) = position(ra_fixture); | ||
37 | let sema = Semantics::new(&db); | ||
38 | let file = sema.parse(position.file_id); | ||
39 | let impl_block: ast::Impl = | ||
40 | sema.find_node_at_offset_with_descend(file.syntax(), position.offset).unwrap(); | ||
41 | let items = crate::traits::get_missing_assoc_items(&sema, &impl_block); | ||
42 | let actual = items | ||
43 | .into_iter() | ||
44 | .map(|item| item.name(&db).unwrap().to_string()) | ||
45 | .collect::<Vec<_>>() | ||
46 | .join("\n"); | ||
47 | expect.assert_eq(&actual); | ||
48 | } | ||
49 | |||
50 | #[test] | ||
51 | fn resolve_trait() { | ||
52 | check_trait( | ||
53 | r#" | ||
54 | pub trait Foo { | ||
55 | fn bar(); | ||
56 | } | ||
57 | impl Foo for u8 { | ||
58 | <|> | ||
59 | } | ||
60 | "#, | ||
61 | expect![["Foo"]], | ||
62 | ); | ||
63 | check_trait( | ||
64 | r#" | ||
65 | pub trait Foo { | ||
66 | fn bar(); | ||
67 | } | ||
68 | impl Foo for u8 { | ||
69 | fn bar() { | ||
70 | fn baz() { | ||
71 | <|> | ||
72 | } | ||
73 | baz(); | ||
74 | } | ||
75 | } | ||
76 | "#, | ||
77 | expect![["Foo"]], | ||
78 | ); | ||
79 | check_trait( | ||
80 | r#" | ||
81 | pub trait Foo { | ||
82 | fn bar(); | ||
83 | } | ||
84 | pub struct Bar; | ||
85 | impl Bar { | ||
86 | <|> | ||
87 | } | ||
88 | "#, | ||
89 | expect![[""]], | ||
90 | ); | ||
91 | } | ||
92 | |||
93 | #[test] | ||
94 | fn missing_assoc_items() { | ||
95 | check_missing_assoc( | ||
96 | r#" | ||
97 | pub trait Foo { | ||
98 | const FOO: u8; | ||
99 | fn bar(); | ||
100 | } | ||
101 | impl Foo for u8 { | ||
102 | <|> | ||
103 | }"#, | ||
104 | expect![[r#" | ||
105 | FOO | ||
106 | bar"#]], | ||
107 | ); | ||
108 | |||
109 | check_missing_assoc( | ||
110 | r#" | ||
111 | pub trait Foo { | ||
112 | const FOO: u8; | ||
113 | fn bar(); | ||
114 | } | ||
115 | impl Foo for u8 { | ||
116 | const FOO: u8 = 10; | ||
117 | <|> | ||
118 | }"#, | ||
119 | expect![[r#" | ||
120 | bar"#]], | ||
121 | ); | ||
122 | |||
123 | check_missing_assoc( | ||
124 | r#" | ||
125 | pub trait Foo { | ||
126 | const FOO: u8; | ||
127 | fn bar(); | ||
128 | } | ||
129 | impl Foo for u8 { | ||
130 | const FOO: u8 = 10; | ||
131 | fn bar() {<|>} | ||
132 | }"#, | ||
133 | expect![[r#""#]], | ||
134 | ); | ||
135 | |||
136 | check_missing_assoc( | ||
137 | r#" | ||
138 | pub struct Foo; | ||
139 | impl Foo { | ||
140 | fn bar() {<|>} | ||
141 | }"#, | ||
142 | expect![[r#""#]], | ||
143 | ); | ||
144 | } | ||