@@ -76,3 +76,152 @@ pub fn get_missing_assoc_items(
7676 . collect ( )
7777 } )
7878}
79+
80+ #[ cfg( test) ]
81+ mod tests {
82+ use crate :: RootDatabase ;
83+ use base_db:: { fixture:: ChangeFixture , FilePosition } ;
84+ use expect_test:: { expect, Expect } ;
85+ use hir:: Semantics ;
86+ use syntax:: ast:: { self , AstNode } ;
87+ use test_utils:: RangeOrOffset ;
88+
89+ /// Creates analysis from a multi-file fixture, returns positions marked with <|>.
90+ pub ( crate ) fn position ( ra_fixture : & str ) -> ( RootDatabase , FilePosition ) {
91+ let change_fixture = ChangeFixture :: parse ( ra_fixture) ;
92+ let mut database = RootDatabase :: default ( ) ;
93+ database. apply_change ( change_fixture. change ) ;
94+ let ( file_id, range_or_offset) =
95+ change_fixture. file_position . expect ( "expected a marker (<|>)" ) ;
96+ let offset = match range_or_offset {
97+ RangeOrOffset :: Range ( _) => panic ! ( ) ,
98+ RangeOrOffset :: Offset ( it) => it,
99+ } ;
100+ ( database, FilePosition { file_id, offset } )
101+ }
102+
103+ fn check_trait ( ra_fixture : & str , expect : Expect ) {
104+ let ( db, position) = position ( ra_fixture) ;
105+ let sema = Semantics :: new ( & db) ;
106+ let file = sema. parse ( position. file_id ) ;
107+ let impl_block: ast:: Impl =
108+ sema. find_node_at_offset_with_descend ( file. syntax ( ) , position. offset ) . unwrap ( ) ;
109+ let trait_ = crate :: traits:: resolve_target_trait ( & sema, & impl_block) ;
110+ let actual = match trait_ {
111+ Some ( trait_) => trait_. name ( & db) . to_string ( ) ,
112+ None => String :: new ( ) ,
113+ } ;
114+ expect. assert_eq ( & actual) ;
115+ }
116+
117+ fn check_missing_assoc ( ra_fixture : & str , expect : Expect ) {
118+ let ( db, position) = position ( ra_fixture) ;
119+ let sema = Semantics :: new ( & db) ;
120+ let file = sema. parse ( position. file_id ) ;
121+ let impl_block: ast:: Impl =
122+ sema. find_node_at_offset_with_descend ( file. syntax ( ) , position. offset ) . unwrap ( ) ;
123+ let items = crate :: traits:: get_missing_assoc_items ( & sema, & impl_block) ;
124+ let actual = items
125+ . into_iter ( )
126+ . map ( |item| item. name ( & db) . unwrap ( ) . to_string ( ) )
127+ . collect :: < Vec < _ > > ( )
128+ . join ( "\n " ) ;
129+ expect. assert_eq ( & actual) ;
130+ }
131+
132+ #[ test]
133+ fn resolve_trait ( ) {
134+ check_trait (
135+ r#"
136+ pub trait Foo {
137+ fn bar();
138+ }
139+ impl Foo for u8 {
140+ <|>
141+ }
142+ "# ,
143+ expect ! [ [ "Foo" ] ] ,
144+ ) ;
145+ check_trait (
146+ r#"
147+ pub trait Foo {
148+ fn bar();
149+ }
150+ impl Foo for u8 {
151+ fn bar() {
152+ fn baz() {
153+ <|>
154+ }
155+ baz();
156+ }
157+ }
158+ "# ,
159+ expect ! [ [ "Foo" ] ] ,
160+ ) ;
161+ check_trait (
162+ r#"
163+ pub trait Foo {
164+ fn bar();
165+ }
166+ pub struct Bar;
167+ impl Bar {
168+ <|>
169+ }
170+ "# ,
171+ expect ! [ [ "" ] ] ,
172+ ) ;
173+ }
174+
175+ #[ test]
176+ fn missing_assoc_items ( ) {
177+ check_missing_assoc (
178+ r#"
179+ pub trait Foo {
180+ const FOO: u8;
181+ fn bar();
182+ }
183+ impl Foo for u8 {
184+ <|>
185+ }"# ,
186+ expect ! [ [ r#"
187+ FOO
188+ bar"# ] ] ,
189+ ) ;
190+
191+ check_missing_assoc (
192+ r#"
193+ pub trait Foo {
194+ const FOO: u8;
195+ fn bar();
196+ }
197+ impl Foo for u8 {
198+ const FOO: u8 = 10;
199+ <|>
200+ }"# ,
201+ expect ! [ [ r#"
202+ bar"# ] ] ,
203+ ) ;
204+
205+ check_missing_assoc (
206+ r#"
207+ pub trait Foo {
208+ const FOO: u8;
209+ fn bar();
210+ }
211+ impl Foo for u8 {
212+ const FOO: u8 = 10;
213+ fn bar() {<|>}
214+ }"# ,
215+ expect ! [ [ r#""# ] ] ,
216+ ) ;
217+
218+ check_missing_assoc (
219+ r#"
220+ pub struct Foo;
221+ impl Foo {
222+ fn bar() {<|>}
223+ }"# ,
224+ expect ! [ [ r#""# ] ] ,
225+ ) ;
226+ }
227+ }
0 commit comments