@@ -147,23 +147,50 @@ suite("TestController", () => {
147147 ) ;
148148 }
149149
150- function createWorkspaceWithTestFile ( ) {
150+ function createWorkspaceWithTestFile (
151+ options : {
152+ testDir ?: string ;
153+ testFileName ?: string ;
154+ testContent ?: string ;
155+ index ?: number ;
156+ additionalFiles ?: Array < { path : string ; content : string } > ;
157+ } = { } ,
158+ ) {
159+ const {
160+ testDir = "test" ,
161+ testFileName = "foo_test.rb" ,
162+ testContent = "require 'test_helper'\n\nclass FooTest < Minitest::Test; def test_foo; end; end" ,
163+ index = 1 ,
164+ additionalFiles = [ ] ,
165+ } = options ;
166+
151167 const workspacePath = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , "ruby-lsp-test-controller-" ) ) ;
152168 const workspaceUri = vscode . Uri . file ( workspacePath ) ;
153169
154- fs . mkdirSync ( path . join ( workspaceUri . fsPath , "test" ) ) ;
155- const testFilePath = path . join ( workspaceUri . fsPath , "test" , "foo_test.rb" ) ;
156- fs . writeFileSync ( testFilePath , "require 'test_helper'\n\nclass FooTest < Minitest::Test; def test_foo; end; end" ) ;
170+ fs . mkdirSync ( path . join ( workspaceUri . fsPath , testDir ) , { recursive : true } ) ;
171+ const testFilePath = path . join ( workspaceUri . fsPath , testDir , testFileName ) ;
172+ fs . writeFileSync ( testFilePath , testContent ) ;
173+
174+ // Create additional files if specified
175+ additionalFiles . forEach ( ( { path : filePath , content } ) => {
176+ const fullPath = path . join ( workspaceUri . fsPath , filePath ) ;
177+ fs . mkdirSync ( path . dirname ( fullPath ) , { recursive : true } ) ;
178+ fs . writeFileSync ( fullPath , content ) ;
179+ } ) ;
157180
158181 const workspaceFolder : vscode . WorkspaceFolder = {
159182 uri : workspaceUri ,
160183 name : path . basename ( workspacePath ) ,
161- index : 1 ,
184+ index,
162185 } ;
163186
164187 return { workspaceFolder, testFileUri : vscode . Uri . file ( testFilePath ) } ;
165188 }
166189
190+ function cleanupWorkspace ( workspaceFolder : vscode . WorkspaceFolder ) {
191+ fs . rmSync ( workspaceFolder . uri . fsPath , { recursive : true , force : true } ) ;
192+ }
193+
167194 function stubWorkspaceOperations ( ...workspaces : vscode . WorkspaceFolder [ ] ) {
168195 workspaceStubs . forEach ( ( stub ) => stub . restore ( ) ) ;
169196 workspaceStubs = [ ] ;
@@ -927,4 +954,110 @@ suite("TestController", () => {
927954
928955 assert . ok ( spy . calledOnce ) ;
929956 } ) ;
957+
958+ test ( "does not discover tests in .bundle directory" , async ( ) => {
959+ const { workspaceFolder, testFileUri } = createWorkspaceWithTestFile ( {
960+ testFileName : "my_test.rb" ,
961+ testContent : "class MyTest < Minitest::Test; end" ,
962+ index : 0 ,
963+ additionalFiles : [
964+ {
965+ path : ".bundle/gems/test/gem_test.rb" ,
966+ content : "class GemTest < Minitest::Test; end" ,
967+ } ,
968+ ] ,
969+ } ) ;
970+
971+ stubWorkspaceOperations ( workspaceFolder ) ;
972+
973+ await controller . testController . resolveHandler ! ( undefined ) ;
974+
975+ const collection = controller . testController . items ;
976+ const testDir = collection . get ( vscode . Uri . joinPath ( workspaceFolder . uri , "test" ) . toString ( ) ) ;
977+
978+ // Should find the regular test file
979+ assert . ok ( testDir ) ;
980+ const regularTest = testDir . children . get ( testFileUri . toString ( ) ) ;
981+ assert . ok ( regularTest , "Regular test file should be discovered" ) ;
982+
983+ // Should NOT find the bundled gem test file
984+ const bundledTestDir = collection . get (
985+ vscode . Uri . joinPath ( workspaceFolder . uri , ".bundle" , "gems" , "test" ) . toString ( ) ,
986+ ) ;
987+ assert . strictEqual ( bundledTestDir , undefined , "Bundled gem directory should not be discovered" ) ;
988+
989+ cleanupWorkspace ( workspaceFolder ) ;
990+ } ) ;
991+
992+ test ( "does not discover tests in vendor/bundle directory" , async ( ) => {
993+ const { workspaceFolder, testFileUri } = createWorkspaceWithTestFile ( {
994+ testDir : "spec" ,
995+ testFileName : "my_spec.rb" ,
996+ testContent : "RSpec.describe 'MySpec' do; end" ,
997+ index : 0 ,
998+ additionalFiles : [
999+ {
1000+ path : "vendor/bundle/gems/spec/gem_spec.rb" ,
1001+ content : "RSpec.describe 'GemSpec' do; end" ,
1002+ } ,
1003+ ] ,
1004+ } ) ;
1005+
1006+ stubWorkspaceOperations ( workspaceFolder ) ;
1007+
1008+ await controller . testController . resolveHandler ! ( undefined ) ;
1009+
1010+ const collection = controller . testController . items ;
1011+ const specDir = collection . get ( vscode . Uri . joinPath ( workspaceFolder . uri , "spec" ) . toString ( ) ) ;
1012+
1013+ // Should find the regular spec file
1014+ assert . ok ( specDir ) ;
1015+ const regularSpec = specDir . children . get ( testFileUri . toString ( ) ) ;
1016+ assert . ok ( regularSpec , "Regular spec file should be discovered" ) ;
1017+
1018+ // Should NOT find the bundled gem test file
1019+ const bundledTestDir = collection . get (
1020+ vscode . Uri . joinPath ( workspaceFolder . uri , "vendor" , "bundle" , "gems" , "test" ) . toString ( ) ,
1021+ ) ;
1022+ assert . strictEqual ( bundledTestDir , undefined , "Bundled gem directory should not be discovered" ) ;
1023+
1024+ cleanupWorkspace ( workspaceFolder ) ;
1025+ } ) ;
1026+
1027+ suite ( "isInBundledGems" , ( ) => {
1028+ test ( "detects files in .bundle directory" , ( ) => {
1029+ const uri = vscode . Uri . file ( "/workspace/.bundle/gems/ruby/3.3.0/gems/rspec-core-3.12.0/spec/rspec_spec.rb" ) ;
1030+ assert . ok ( ( controller as any ) . isInBundledGems ( uri ) ) ;
1031+ } ) ;
1032+
1033+ test ( "detects files in vendor/bundle directory" , ( ) => {
1034+ const uri = vscode . Uri . file ( "/workspace/vendor/bundle/ruby/3.3.0/gems/rspec-core-3.12.0/spec/rspec_spec.rb" ) ;
1035+ assert . ok ( ( controller as any ) . isInBundledGems ( uri ) ) ;
1036+ } ) ;
1037+
1038+ test ( "detects files in nested .bundle paths" , ( ) => {
1039+ const uri = vscode . Uri . file ( "/workspace/subfolder/.bundle/ruby/3.3.0/gems/minitest-5.0.0/test/minitest_test.rb" ) ;
1040+ assert . ok ( ( controller as any ) . isInBundledGems ( uri ) ) ;
1041+ } ) ;
1042+
1043+ test ( "does not detect regular test files" , ( ) => {
1044+ const uri = vscode . Uri . file ( "/workspace/test/models/user_test.rb" ) ;
1045+ assert . strictEqual ( ( controller as any ) . isInBundledGems ( uri ) , false ) ;
1046+ } ) ;
1047+
1048+ test ( "does not detect spec files in regular paths" , ( ) => {
1049+ const uri = vscode . Uri . file ( "/workspace/spec/models/user_spec.rb" ) ;
1050+ assert . strictEqual ( ( controller as any ) . isInBundledGems ( uri ) , false ) ;
1051+ } ) ;
1052+
1053+ test ( "does not detect files with 'bundle' in name but not in bundled gems directory" , ( ) => {
1054+ const uri = vscode . Uri . file ( "/workspace/test/bundle_test.rb" ) ;
1055+ assert . strictEqual ( ( controller as any ) . isInBundledGems ( uri ) , false ) ;
1056+ } ) ;
1057+
1058+ test ( "does not detect files with 'vendor' in name but not in vendor/bundle" , ( ) => {
1059+ const uri = vscode . Uri . file ( "/workspace/test/vendor_test.rb" ) ;
1060+ assert . strictEqual ( ( controller as any ) . isInBundledGems ( uri ) , false ) ;
1061+ } ) ;
1062+ } ) ;
9301063} ) ;
0 commit comments