@@ -194,4 +194,69 @@ def method_mixed(required, optional = nil, *rest, keyword:, **kwargs, &block)
194194 assert_equal ( 'arg1 (required), arg2 (required)' , simple_method_item [ :detail ] , 'should include parameter details' )
195195 end
196196 end
197+
198+ describe 'module inclusion' do
199+ before do
200+ @code_with_include = <<-SOURCE
201+ module FooModule
202+ def foo_method
203+ end
204+
205+ def another_foo_method(param1)
206+ end
207+ end
208+
209+ class BarClass
210+ include FooModule
211+
212+ def bar_method
213+ foo # completion should find foo_method from included FooModule module
214+ end
215+ end
216+ SOURCE
217+ @include_parser = RubyLanguageServer ::ScopeParser . new ( @code_with_include )
218+ end
219+
220+ it 'should track included modules in scope' do
221+ all_scopes = @include_parser . root_scope . self_and_descendants
222+ bar_class = all_scopes . find_by_path ( 'BarClass' )
223+
224+ assert bar_class , 'BarClass should exist'
225+ included_modules = bar_class . parsed_included_modules
226+ assert_equal ( [ 'FooModule' ] , included_modules , 'BarClass should have FooModule in its included modules' )
227+ end
228+
229+ it 'should include methods from included modules in completions' do
230+ all_scopes = @include_parser . root_scope . self_and_descendants
231+ bar_method_scope = all_scopes . find_by_path ( 'BarClass#bar_method' )
232+
233+ assert bar_method_scope , 'bar_method scope should exist'
234+
235+ # Get completions for 'foo' prefix within BarClass#bar_method
236+ context = [ 'foo' ]
237+ position_scopes = @include_parser . root_scope . self_and_descendants . for_line ( bar_method_scope . top_line + 1 )
238+ completions = scope_completions ( context . last , position_scopes )
239+
240+ # Should include foo_method from the included FooModule module
241+ completion_names = completions . map ( &:first )
242+ assert_includes ( completion_names , 'foo_method' , 'Should find foo_method from included module FooModule' )
243+ assert_includes ( completion_names , 'another_foo_method' , 'Should find another_foo_method from included module FooModule' )
244+ end
245+
246+ it 'should include method parameters from included modules' do
247+ all_scopes = @include_parser . root_scope . self_and_descendants
248+ bar_method_scope = all_scopes . find_by_path ( 'BarClass#bar_method' )
249+
250+ # Get completions for 'another_foo' prefix
251+ context = [ 'another_foo' ]
252+ completions = RubyLanguageServer ::Completion . completion ( context , bar_method_scope , all_scopes )
253+
254+ # Find the another_foo_method completion
255+ another_foo_item = completions [ :items ] . find { |item | item [ :label ] . start_with? ( 'another_foo_method' ) }
256+
257+ assert another_foo_item , 'another_foo_method should be in completions'
258+ assert_equal ( 'another_foo_method(param1)' , another_foo_item [ :label ] , 'should include parameters in label' )
259+ assert_equal ( 'another_foo_method(${1:param1})' , another_foo_item [ :insertText ] , 'should include parameter snippet' )
260+ end
261+ end
197262end
0 commit comments