33 */
44
55import { describe , it , expect , beforeAll , afterAll , afterEach } from 'vitest' ;
6- import { writeFileSync , rmSync , chmodSync , mkdirSync , existsSync } from 'fs' ;
6+ import { writeFileSync , rmSync , chmodSync , mkdirSync } from 'fs' ;
77import { execFileSync } from 'child_process' ;
88import { isAbsolute , join } from 'path' ;
99import { createProjectTempDir } from '../../../src/utils/temp-dir' ;
@@ -587,20 +587,12 @@ describe('resolveCodeQLBinary', () => {
587587 delete process . env . CODEQL_PATH ;
588588 const result = resolveCodeQLBinary ( ) ;
589589 expect ( result ) . toBe ( 'codeql' ) ;
590- // getResolvedCodeQLDir() may be non-null if the vscode-codeql
591- // distribution is installed on this machine (auto-discovery)
592- const dir = getResolvedCodeQLDir ( ) ;
593- expect ( dir === null || typeof dir === 'string' ) . toBe ( true ) ;
594590 } ) ;
595591
596592 it ( 'should default to "codeql" when CODEQL_PATH is empty' , ( ) => {
597593 process . env . CODEQL_PATH = '' ;
598594 const result = resolveCodeQLBinary ( ) ;
599595 expect ( result ) . toBe ( 'codeql' ) ;
600- // getResolvedCodeQLDir() may be non-null if the vscode-codeql
601- // distribution is installed on this machine (auto-discovery)
602- const dir = getResolvedCodeQLDir ( ) ;
603- expect ( dir === null || typeof dir === 'string' ) . toBe ( true ) ;
604596 } ) ;
605597
606598 it ( 'should return bare codeql command and set dir to parent directory' , ( ) => {
@@ -690,10 +682,6 @@ describe('CODEQL_PATH - PATH prepend integration', () => {
690682 process . env . CODEQL_PATH = '/some/changed/path/codeql' ;
691683 const second = resolveCodeQLBinary ( ) ;
692684 expect ( second ) . toBe ( 'codeql' ) ;
693- // getResolvedCodeQLDir() may be non-null if vscode-codeql
694- // distribution was auto-discovered on the first resolve()
695- const dir = getResolvedCodeQLDir ( ) ;
696- expect ( dir === null || typeof dir === 'string' ) . toBe ( true ) ;
697685 } ) ;
698686
699687 it . skipIf ( process . platform === 'win32' ) ( 'should prepend CODEQL_PATH directory to child process PATH' , async ( ) => {
@@ -823,66 +811,89 @@ describe('getVsCodeGlobalStorageCandidates', () => {
823811} ) ;
824812
825813describe ( 'discoverVsCodeCodeQLDistribution' , ( ) => {
814+ const binaryName = process . platform === 'win32' ? 'codeql.exe' : 'codeql' ;
815+
826816 it ( 'should return undefined when no vscode-codeql storage exists' , ( ) => {
827- // In the test environment, the vscode-codeql storage is unlikely to exist
828- // at the standard location, so discovery should return undefined.
829- // This is effectively a no-op test that ensures the function handles
830- // missing directories gracefully.
831- const result = discoverVsCodeCodeQLDistribution ( ) ;
832- // Result depends on whether vscode-codeql is installed — just verify it doesn't throw
833- expect ( result === undefined || typeof result === 'string' ) . toBe ( true ) ;
817+ const tmpDir = createProjectTempDir ( 'vscode-codeql-no-storage-' ) ;
818+ try {
819+ // No extension storage dirs created inside tmpDir
820+ const result = discoverVsCodeCodeQLDistribution ( [ tmpDir ] ) ;
821+ expect ( result ) . toBeUndefined ( ) ;
822+ } finally {
823+ rmSync ( tmpDir , { recursive : true , force : true } ) ;
824+ }
834825 } ) ;
835826
836- it ( 'should discover CLI from a simulated distribution directory ' , ( ) => {
837- const tmpDir = createProjectTempDir ( 'vscode-codeql-discovery-test -' ) ;
827+ it ( 'should discover CLI from distribution.json fast path ' , ( ) => {
828+ const tmpDir = createProjectTempDir ( 'vscode-codeql-json-fastpath -' ) ;
838829 const codeqlStorage = join ( tmpDir , 'github.vscode-codeql' ) ;
839830 const distDir = join ( codeqlStorage , 'distribution3' , 'codeql' ) ;
840-
841- // Create the distribution directory structure with a fake binary
842831 mkdirSync ( distDir , { recursive : true } ) ;
843- const binaryPath = join ( distDir , process . platform === 'win32' ? 'codeql.exe' : 'codeql' ) ;
832+ const binaryPath = join ( distDir , binaryName ) ;
844833 writeFileSync ( binaryPath , '#!/bin/sh\necho test' , { mode : 0o755 } ) ;
845-
846- // Also create distribution.json
847- writeFileSync (
848- join ( codeqlStorage , 'distribution.json' ) ,
849- JSON . stringify ( { folderIndex : 3 } ) ,
850- ) ;
851-
834+ writeFileSync ( join ( codeqlStorage , 'distribution.json' ) , JSON . stringify ( { folderIndex : 3 } ) ) ;
852835 try {
853- // We can't easily test discoverVsCodeCodeQLDistribution directly because
854- // it uses hardcoded platform-specific paths. Instead, test the behavior
855- // by creating the structure and verifying the file was created correctly.
856- expect ( existsSync ( binaryPath ) ) . toBe ( true ) ;
836+ const result = discoverVsCodeCodeQLDistribution ( [ tmpDir ] ) ;
837+ expect ( result ) . toBe ( binaryPath ) ;
857838 } finally {
858839 rmSync ( tmpDir , { recursive : true , force : true } ) ;
859840 }
860841 } ) ;
861842
862- it ( 'should prefer distribution.json folderIndex when available ' , ( ) => {
863- const tmpDir = createProjectTempDir ( 'vscode-codeql-json-test -' ) ;
843+ it ( 'should fall back to directory scan when distribution.json is missing ' , ( ) => {
844+ const tmpDir = createProjectTempDir ( 'vscode-codeql-scan-fallback -' ) ;
864845 const codeqlStorage = join ( tmpDir , 'github.vscode-codeql' ) ;
846+ const dist1 = join ( codeqlStorage , 'distribution1' , 'codeql' ) ;
847+ const dist3 = join ( codeqlStorage , 'distribution3' , 'codeql' ) ;
848+ mkdirSync ( dist1 , { recursive : true } ) ;
849+ mkdirSync ( dist3 , { recursive : true } ) ;
850+ writeFileSync ( join ( dist1 , binaryName ) , '#!/bin/sh\necho v1' , { mode : 0o755 } ) ;
851+ writeFileSync ( join ( dist3 , binaryName ) , '#!/bin/sh\necho v3' , { mode : 0o755 } ) ;
852+ // No distribution.json — scan should pick the highest-numbered directory
853+ try {
854+ const result = discoverVsCodeCodeQLDistribution ( [ tmpDir ] ) ;
855+ expect ( result ) . toBe ( join ( dist3 , binaryName ) ) ;
856+ } finally {
857+ rmSync ( tmpDir , { recursive : true , force : true } ) ;
858+ }
859+ } ) ;
865860
866- // Create two distribution directories
867- const dist2Dir = join ( codeqlStorage , 'distribution2' , 'codeql' ) ;
868- const dist3Dir = join ( codeqlStorage , 'distribution3' , 'codeql' ) ;
869- mkdirSync ( dist2Dir , { recursive : true } ) ;
870- mkdirSync ( dist3Dir , { recursive : true } ) ;
871-
872- const binaryName = process . platform === 'win32' ? 'codeql.exe' : 'codeql' ;
873- writeFileSync ( join ( dist2Dir , binaryName ) , '#!/bin/sh\necho v2' , { mode : 0o755 } ) ;
874- writeFileSync ( join ( dist3Dir , binaryName ) , '#!/bin/sh\necho v3' , { mode : 0o755 } ) ;
875-
876- // distribution.json points to distribution3
877- writeFileSync (
878- join ( codeqlStorage , 'distribution.json' ) ,
879- JSON . stringify ( { folderIndex : 3 } ) ,
880- ) ;
861+ it ( 'should prefer distribution.json folderIndex over highest-numbered directory' , ( ) => {
862+ const tmpDir = createProjectTempDir ( 'vscode-codeql-json-precedence-' ) ;
863+ const codeqlStorage = join ( tmpDir , 'github.vscode-codeql' ) ;
864+ const dist2 = join ( codeqlStorage , 'distribution2' , 'codeql' ) ;
865+ const dist3 = join ( codeqlStorage , 'distribution3' , 'codeql' ) ;
866+ mkdirSync ( dist2 , { recursive : true } ) ;
867+ mkdirSync ( dist3 , { recursive : true } ) ;
868+ writeFileSync ( join ( dist2 , binaryName ) , '#!/bin/sh\necho v2' , { mode : 0o755 } ) ;
869+ writeFileSync ( join ( dist3 , binaryName ) , '#!/bin/sh\necho v3' , { mode : 0o755 } ) ;
870+ // distribution.json points to distribution2 (lower index than distribution3)
871+ writeFileSync ( join ( codeqlStorage , 'distribution.json' ) , JSON . stringify ( { folderIndex : 2 } ) ) ;
872+ try {
873+ const result = discoverVsCodeCodeQLDistribution ( [ tmpDir ] ) ;
874+ // Should pick distribution2 per distribution.json, not distribution3
875+ expect ( result ) . toBe ( join ( dist2 , binaryName ) ) ;
876+ } finally {
877+ rmSync ( tmpDir , { recursive : true , force : true } ) ;
878+ }
879+ } ) ;
881880
881+ it ( 'should scan directories sorted by descending numeric suffix' , ( ) => {
882+ const tmpDir = createProjectTempDir ( 'vscode-codeql-scan-order-' ) ;
883+ const codeqlStorage = join ( tmpDir , 'github.vscode-codeql' ) ;
884+ const dist1 = join ( codeqlStorage , 'distribution1' , 'codeql' ) ;
885+ const dist2 = join ( codeqlStorage , 'distribution2' , 'codeql' ) ;
886+ const dist10 = join ( codeqlStorage , 'distribution10' , 'codeql' ) ;
887+ mkdirSync ( dist1 , { recursive : true } ) ;
888+ mkdirSync ( dist2 , { recursive : true } ) ;
889+ mkdirSync ( dist10 , { recursive : true } ) ;
890+ writeFileSync ( join ( dist1 , binaryName ) , '#!/bin/sh\necho v1' , { mode : 0o755 } ) ;
891+ writeFileSync ( join ( dist2 , binaryName ) , '#!/bin/sh\necho v2' , { mode : 0o755 } ) ;
892+ writeFileSync ( join ( dist10 , binaryName ) , '#!/bin/sh\necho v10' , { mode : 0o755 } ) ;
882893 try {
883- // Verify both files exist
884- expect ( existsSync ( join ( dist3Dir , binaryName ) ) ) . toBe ( true ) ;
885- expect ( existsSync ( join ( dist2Dir , binaryName ) ) ) . toBe ( true ) ;
894+ const result = discoverVsCodeCodeQLDistribution ( [ tmpDir ] ) ;
895+ // distribution10 > distribution2 > distribution1 by numeric sort
896+ expect ( result ) . toBe ( join ( dist10 , binaryName ) ) ;
886897 } finally {
887898 rmSync ( tmpDir , { recursive : true , force : true } ) ;
888899 }
@@ -906,10 +917,6 @@ describe('resolveCodeQLBinary - vscode-codeql auto-discovery', () => {
906917 // This will either find a vscode-codeql distribution or fall back to bare 'codeql'
907918 const result = resolveCodeQLBinary ( ) ;
908919 expect ( result ) . toBe ( 'codeql' ) ;
909- // If a distribution was found, resolvedCodeQLDir will be set
910- // If not, it will be null — either is acceptable
911- const dir = getResolvedCodeQLDir ( ) ;
912- expect ( dir === null || typeof dir === 'string' ) . toBe ( true ) ;
913920 } ) ;
914921} ) ;
915922
0 commit comments