2021-04-05 13:02:27 +03:00
import {
2026-07-08 14:45:00 +05:30
jest ,
describe ,
it ,
expect ,
beforeEach ,
afterEach ,
beforeAll ,
afterAll
} from '@jest/globals' ;
import type {
2021-04-05 13:02:27 +03:00
JavaDownloadRelease ,
JavaInstallerOptions ,
JavaInstallerResults
2026-07-08 14:45:00 +05:30
} from '../../src/distributions/base-models.js' ;
import path from 'path' ;
import * as semver from 'semver' ;
2021-04-05 13:02:27 +03:00
2022-10-10 17:47:17 -06:00
import os from 'os' ;
2026-07-08 14:45:00 +05:30
// Mock @actions/core before importing source modules that depend on it
jest . unstable_mockModule ( '@actions/core' , ( ) = > ( {
info : jest.fn ( ) ,
warning : jest.fn ( ) ,
debug : jest.fn ( ) ,
error : jest.fn ( ) ,
notice : jest.fn ( ) ,
setFailed : jest.fn ( ) ,
setOutput : jest.fn ( ) ,
getInput : jest.fn ( ) ,
getBooleanInput : jest.fn ( ) ,
getMultilineInput : jest.fn ( ) ,
addPath : jest.fn ( ) ,
exportVariable : jest.fn ( ) ,
saveState : jest.fn ( ) ,
getState : jest.fn ( ) ,
setSecret : jest.fn ( ) ,
isDebug : jest.fn ( ( ) = > false ) ,
startGroup : jest.fn ( ) ,
endGroup : jest.fn ( ) ,
group : jest.fn ( ( _name : string , fn : ( ) = > Promise < unknown > ) = > fn ( ) ) ,
toPlatformPath : jest.fn ( ( p : string ) = > p ) ,
toWin32Path : jest.fn ( ( p : string ) = > p ) ,
toPosixPath : jest.fn ( ( p : string ) = > p )
} ) ) ;
jest . unstable_mockModule ( '@actions/tool-cache' , ( ) = > ( {
find : jest.fn ( ) ,
findAllVersions : jest.fn ( ) ,
downloadTool : jest.fn ( ) ,
extractZip : jest.fn ( ) ,
extractTar : jest.fn ( ) ,
extract7z : jest.fn ( ) ,
extractXar : jest.fn ( ) ,
cacheDir : jest.fn ( ) ,
cacheFile : jest.fn ( ) ,
getManifestFromRepo : jest.fn ( ) ,
findFromManifest : jest.fn ( ) ,
evaluateVersions : jest.fn ( ) ,
HTTPError : class HTTPError extends Error {
httpStatusCode : number ;
constructor ( statusCode : number ) {
super ( ` HTTP Error: ${ statusCode } ` ) ;
this . httpStatusCode = statusCode ;
}
}
} ) ) ;
const real_util_module = await import ( '../../src/util.js' ) ;
jest . unstable_mockModule ( '../../src/util.js' , ( ) = > ( {
. . . real_util_module ,
extractJdkFile : jest.fn ( ) ,
getDownloadArchiveExtension : jest.fn ( ) ,
getToolcachePath : jest.fn ( ) ,
isJobStatusSuccess : jest.fn ( ) ,
renameWinArchive : jest.fn ( ) ,
isVersionSatisfies : real_util_module.isVersionSatisfies ,
getTempDir : real_util_module.getTempDir
} ) ) ;
// Dynamic imports after mocking
const core = await import ( '@actions/core' ) ;
const tc = await import ( '@actions/tool-cache' ) ;
const util = await import ( '../../src/util.js' ) ;
const { JavaBase } = await import ( '../../src/distributions/base-installer.js' ) ;
2021-04-05 13:02:27 +03:00
class EmptyJavaBase extends JavaBase {
constructor ( installerOptions : JavaInstallerOptions ) {
super ( 'Empty' , installerOptions ) ;
}
2023-03-09 14:49:35 +02:00
protected async downloadTool (
javaRelease : JavaDownloadRelease
) : Promise < JavaInstallerResults > {
2021-04-05 13:02:27 +03:00
return {
version : '11.0.9' ,
2023-03-09 14:49:35 +02:00
path : path.join (
'toolcache' ,
this . toolcacheFolderName ,
'11.0.9' ,
this . architecture
)
2021-04-05 13:02:27 +03:00
} ;
}
2023-03-09 14:49:35 +02:00
protected async findPackageForDownload (
range : string
) : Promise < JavaDownloadRelease > {
2021-04-05 13:02:27 +03:00
const availableVersion = '11.0.9' ;
if ( ! semver . satisfies ( availableVersion , range ) ) {
2026-04-13 23:14:45 +05:30
throw this . createVersionNotFoundError ( range , [ availableVersion ] ) ;
2021-04-05 13:02:27 +03:00
}
return {
version : availableVersion ,
url : ` some/random_url/java/ ${ availableVersion } `
} ;
}
}
describe ( 'findInToolcache' , ( ) = > {
const actualJavaVersion = '11.0.8' ;
const javaPath = path . join ( 'Java_Empty_jdk' , actualJavaVersion , 'x64' ) ;
let mockJavaBase : EmptyJavaBase ;
2026-07-08 14:45:00 +05:30
let spyGetToolcachePath : any ;
let spyTcFindAllVersions : any ;
2021-04-05 13:02:27 +03:00
beforeEach ( ( ) = > {
2026-07-08 14:45:00 +05:30
spyGetToolcachePath = util . getToolcachePath as jest . Mock ;
spyTcFindAllVersions = tc . findAllVersions as jest . Mock ;
2021-04-05 13:02:27 +03:00
} ) ;
afterEach ( ( ) = > {
jest . resetAllMocks ( ) ;
jest . clearAllMocks ( ) ;
jest . restoreAllMocks ( ) ;
} ) ;
it . each ( [
[
2023-03-09 14:49:35 +02:00
{
version : '11' ,
architecture : 'x64' ,
packageType : 'jdk' ,
checkLatest : false
} ,
{ version : actualJavaVersion , path : javaPath }
2021-04-05 13:02:27 +03:00
] ,
[
2023-03-09 14:49:35 +02:00
{
version : '11.0' ,
architecture : 'x64' ,
packageType : 'jdk' ,
checkLatest : false
} ,
{ version : actualJavaVersion , path : javaPath }
2021-04-05 13:02:27 +03:00
] ,
[
2023-03-09 14:49:35 +02:00
{
version : '11.0.8' ,
architecture : 'x64' ,
packageType : 'jdk' ,
checkLatest : false
} ,
{ version : actualJavaVersion , path : javaPath }
2021-04-05 13:02:27 +03:00
] ,
[
2023-03-09 14:49:35 +02:00
{
version : '11' ,
architecture : 'x64' ,
packageType : 'jdk' ,
checkLatest : true
} ,
{ version : actualJavaVersion , path : javaPath }
2021-04-05 13:02:27 +03:00
] ,
[
2023-03-09 14:49:35 +02:00
{
version : '11.0' ,
architecture : 'x64' ,
packageType : 'jdk' ,
checkLatest : true
} ,
{ version : actualJavaVersion , path : javaPath }
2021-04-05 13:02:27 +03:00
] ,
[
2023-03-09 14:49:35 +02:00
{
version : '11.0.8' ,
architecture : 'x64' ,
packageType : 'jdk' ,
checkLatest : true
} ,
{ version : actualJavaVersion , path : javaPath }
2021-04-05 13:02:27 +03:00
] ,
2023-03-09 14:49:35 +02:00
[
{
version : '11' ,
architecture : 'x64' ,
packageType : 'jre' ,
checkLatest : false
} ,
null
] ,
[
{
version : '8' ,
architecture : 'x64' ,
packageType : 'jdk' ,
checkLatest : false
} ,
null
] ,
[
{
version : '11' ,
architecture : 'x86' ,
packageType : 'jdk' ,
checkLatest : false
} ,
null
] ,
[
{
version : '11' ,
architecture : 'x86' ,
packageType : 'jre' ,
checkLatest : false
} ,
null
]
2021-04-05 13:02:27 +03:00
] ) ( ` should find java for path %s -> %s ` , ( input , expected ) = > {
spyTcFindAllVersions . mockReturnValue ( [ actualJavaVersion ] ) ;
spyGetToolcachePath . mockImplementation (
( toolname : string , javaVersion : string , architecture : string ) = > {
const semverVersion = new semver . Range ( javaVersion ) ;
2023-03-09 14:49:35 +02:00
if (
path . basename ( javaPath ) !== architecture ||
! javaPath . includes ( toolname )
) {
2021-04-05 13:02:27 +03:00
return '' ;
}
2023-03-09 14:49:35 +02:00
return semver . satisfies ( actualJavaVersion , semverVersion )
? javaPath
: '' ;
2021-04-05 13:02:27 +03:00
}
) ;
mockJavaBase = new EmptyJavaBase ( input ) ;
expect ( mockJavaBase [ 'findInToolcache' ] ( ) ) . toEqual ( expected ) ;
} ) ;
it . each ( [
2023-03-09 14:49:35 +02:00
[ '11' , { version : '11.0.3+2' , versionInPath : '11.0.3-2' } ] ,
[ '11.0' , { version : '11.0.3+2' , versionInPath : '11.0.3-2' } ] ,
[ '11.0.1' , { version : '11.0.1' , versionInPath : '11.0.1' } ] ,
[ '11.0.3' , { version : '11.0.3+2' , versionInPath : '11.0.3-2' } ] ,
[ '15' , { version : '15.0.2+4' , versionInPath : '15.0.2-4' } ] ,
[ 'x' , { version : '15.0.2+4' , versionInPath : '15.0.2-4' } ] ,
[ 'x-ea' , { version : '17.4.4' , versionInPath : '17.4.4-ea' } ] ,
[
'11-ea' ,
{ version : '11.3.3+5.2.1231421' , versionInPath : '11.3.3-ea.5.2.1231421' }
] ,
[ '11.2-ea' , { version : '11.2.1' , versionInPath : '11.2.1-ea' } ] ,
[ '11.2.1-ea' , { version : '11.2.1' , versionInPath : '11.2.1-ea' } ]
] ) (
'should choose correct java from tool-cache for input %s' ,
( input , expected ) = > {
spyTcFindAllVersions . mockReturnValue ( [
'17.4.4-ea' ,
'11.0.2' ,
'15.0.2-4' ,
'11.0.3-2' ,
'11.2.1-ea' ,
'11.3.2-ea' ,
'11.3.2-ea.5' ,
'11.3.3-ea.5.2.1231421' ,
'12.3.2-0' ,
'11.0.1'
] ) ;
spyGetToolcachePath . mockImplementation (
( toolname : string , javaVersion : string , architecture : string ) = >
` /hostedtoolcache/ ${ toolname } / ${ javaVersion } / ${ architecture } `
) ;
mockJavaBase = new EmptyJavaBase ( {
version : input ,
architecture : 'x64' ,
packageType : 'jdk' ,
checkLatest : false
} ) ;
const foundVersion = mockJavaBase [ 'findInToolcache' ] ( ) ;
expect ( foundVersion ) . toEqual ( {
version : expected.version ,
path : ` /hostedtoolcache/Java_Empty_jdk/ ${ expected . versionInPath } /x64 `
} ) ;
}
) ;
2021-04-05 13:02:27 +03:00
} ) ;
describe ( 'setupJava' , ( ) = > {
const actualJavaVersion = '11.0.9' ;
const installedJavaVersion = '11.0.8' ;
const javaPath = path . join ( 'Java_Empty_jdk' , installedJavaVersion , 'x86' ) ;
2023-03-09 14:49:35 +02:00
const javaPathInstalled = path . join (
'toolcache' ,
'Java_Empty_jdk' ,
actualJavaVersion ,
'x86'
) ;
2021-04-05 13:02:27 +03:00
let mockJavaBase : EmptyJavaBase ;
2026-07-08 14:45:00 +05:30
let spyGetToolcachePath : any ;
let spyTcFindAllVersions : any ;
let spyCoreDebug : any ;
let spyCoreInfo : any ;
let spyCoreExportVariable : any ;
let spyCoreAddPath : any ;
let spyCoreSetOutput : any ;
let spyCoreError : any ;
2021-04-05 13:02:27 +03:00
beforeEach ( ( ) = > {
2026-07-08 14:45:00 +05:30
spyGetToolcachePath = util . getToolcachePath as jest . Mock ;
2021-04-05 13:02:27 +03:00
spyGetToolcachePath . mockImplementation (
( toolname : string , javaVersion : string , architecture : string ) = > {
const semverVersion = new semver . Range ( javaVersion ) ;
2023-03-09 14:49:35 +02:00
if (
path . basename ( javaPath ) !== architecture ||
! javaPath . includes ( toolname )
) {
2021-04-05 13:02:27 +03:00
return '' ;
}
2023-03-09 14:49:35 +02:00
return semver . satisfies ( installedJavaVersion , semverVersion )
? javaPath
: '' ;
2021-04-05 13:02:27 +03:00
}
) ;
2026-07-08 14:45:00 +05:30
spyTcFindAllVersions = tc . findAllVersions as jest . Mock ;
2021-04-05 13:02:27 +03:00
spyTcFindAllVersions . mockReturnValue ( [ installedJavaVersion ] ) ;
// Spy on core methods
2026-07-08 14:45:00 +05:30
spyCoreDebug = core . debug as jest . Mock ;
2021-04-05 13:02:27 +03:00
spyCoreDebug . mockImplementation ( ( ) = > undefined ) ;
2026-07-08 14:45:00 +05:30
spyCoreInfo = core . info as jest . Mock ;
2021-04-05 13:02:27 +03:00
spyCoreInfo . mockImplementation ( ( ) = > undefined ) ;
2026-07-08 14:45:00 +05:30
spyCoreAddPath = core . addPath as jest . Mock ;
2021-04-05 13:02:27 +03:00
spyCoreAddPath . mockImplementation ( ( ) = > undefined ) ;
2026-07-08 14:45:00 +05:30
spyCoreExportVariable = core . exportVariable as jest . Mock ;
2021-04-05 13:02:27 +03:00
spyCoreExportVariable . mockImplementation ( ( ) = > undefined ) ;
2026-07-08 14:45:00 +05:30
spyCoreSetOutput = core . setOutput as jest . Mock ;
2021-04-05 13:02:27 +03:00
spyCoreSetOutput . mockImplementation ( ( ) = > undefined ) ;
2022-10-10 17:47:17 -06:00
2026-04-13 23:14:45 +05:30
// Mock core.error to suppress error logs
2026-07-08 14:45:00 +05:30
spyCoreError = core . error as jest . Mock ;
2026-04-13 23:14:45 +05:30
spyCoreError . mockImplementation ( ( ) = > undefined ) ;
2025-08-20 20:07:47 +01:00
jest . spyOn ( os , 'arch' ) . mockReturnValue ( 'x86' as ReturnType < typeof os.arch > ) ;
2021-04-05 13:02:27 +03:00
} ) ;
afterEach ( ( ) = > {
jest . resetAllMocks ( ) ;
jest . clearAllMocks ( ) ;
jest . restoreAllMocks ( ) ;
} ) ;
it . each ( [
[
2023-03-09 14:49:35 +02:00
{
version : '11' ,
architecture : 'x86' ,
packageType : 'jdk' ,
checkLatest : false
} ,
{ version : installedJavaVersion , path : javaPath }
2021-04-05 13:02:27 +03:00
] ,
[
2023-03-09 14:49:35 +02:00
{
version : '11.0' ,
architecture : 'x86' ,
packageType : 'jdk' ,
checkLatest : false
} ,
{ version : installedJavaVersion , path : javaPath }
2021-04-05 13:02:27 +03:00
] ,
[
2023-03-09 14:49:35 +02:00
{
version : '11.0.8' ,
architecture : 'x86' ,
packageType : 'jdk' ,
checkLatest : false
} ,
{ version : installedJavaVersion , path : javaPath }
2022-10-10 17:47:17 -06:00
] ,
[
2023-03-09 14:49:35 +02:00
{ version : '11' , architecture : '' , packageType : 'jdk' , checkLatest : false } ,
{ version : installedJavaVersion , path : javaPath }
2021-04-05 13:02:27 +03:00
]
2023-03-09 14:49:35 +02:00
] ) ( 'should find java locally for %s' , async ( input , expected ) = > {
2021-04-05 13:02:27 +03:00
mockJavaBase = new EmptyJavaBase ( input ) ;
2023-03-09 14:49:35 +02:00
await expect ( mockJavaBase . setupJava ( ) ) . resolves . toEqual ( expected ) ;
2021-04-05 13:02:27 +03:00
expect ( spyGetToolcachePath ) . toHaveBeenCalled ( ) ;
2023-03-09 14:49:35 +02:00
expect ( spyCoreInfo ) . toHaveBeenCalledWith (
` Resolved Java ${ expected . version } from tool-cache `
) ;
expect ( spyCoreInfo ) . toHaveBeenCalledWith (
` Setting Java ${ expected . version } as the default `
) ;
2021-04-05 13:02:27 +03:00
expect ( spyCoreInfo ) . not . toHaveBeenCalledWith (
'Trying to resolve the latest version from remote'
) ;
expect ( spyCoreInfo ) . not . toHaveBeenCalledWith ( 'Trying to download...' ) ;
} ) ;
2026-07-09 15:20:59 -04:00
it ( 'should resolve the latest version from remote when java-version is "latest", even if a version is cached' , async ( ) = > {
mockJavaBase = new EmptyJavaBase ( {
version : 'latest' ,
architecture : 'x86' ,
packageType : 'jdk' ,
checkLatest : false
} ) ;
await expect ( mockJavaBase . setupJava ( ) ) . resolves . toEqual ( {
version : actualJavaVersion ,
path : javaPathInstalled
} ) ;
// `latest` must bypass the tool-cache short-circuit and always resolve remotely
expect ( spyCoreInfo ) . toHaveBeenCalledWith (
'Trying to resolve the latest version from remote'
) ;
expect ( spyCoreInfo ) . toHaveBeenCalledWith ( 'Trying to download...' ) ;
expect ( spyCoreInfo ) . not . toHaveBeenCalledWith (
` Resolved Java ${ installedJavaVersion } from tool-cache `
) ;
} ) ;
2021-04-05 13:02:27 +03:00
it . each ( [
[
2023-03-09 14:49:35 +02:00
{
version : '11' ,
architecture : 'x86' ,
packageType : 'jre' ,
checkLatest : false
} ,
{
path : path.join ( 'toolcache' , 'Java_Empty_jre' , '11.0.9' , 'x86' ) ,
version : '11.0.9'
}
2021-04-05 13:02:27 +03:00
] ,
[
2023-03-09 14:49:35 +02:00
{
version : '11' ,
architecture : 'x64' ,
packageType : 'jdk' ,
checkLatest : false
} ,
{
path : path.join ( 'toolcache' , 'Java_Empty_jdk' , '11.0.9' , 'x64' ) ,
version : '11.0.9'
}
2021-04-05 13:02:27 +03:00
] ,
[
2023-03-09 14:49:35 +02:00
{
version : '11' ,
architecture : 'x64' ,
packageType : 'jre' ,
checkLatest : false
} ,
{
path : path.join ( 'toolcache' , 'Java_Empty_jre' , '11.0.9' , 'x64' ) ,
version : '11.0.9'
}
2022-10-10 17:47:17 -06:00
] ,
[
2023-03-09 14:49:35 +02:00
{ version : '11' , architecture : '' , packageType : 'jre' , checkLatest : false } ,
{
path : path.join ( 'toolcache' , 'Java_Empty_jre' , '11.0.9' , 'x86' ) ,
version : '11.0.9'
}
2021-04-05 13:02:27 +03:00
]
] ) ( 'download java with configuration %s' , async ( input , expected ) = > {
mockJavaBase = new EmptyJavaBase ( input ) ;
await expect ( mockJavaBase . setupJava ( ) ) . resolves . toEqual ( expected ) ;
expect ( spyGetToolcachePath ) . toHaveBeenCalled ( ) ;
expect ( spyCoreAddPath ) . toHaveBeenCalled ( ) ;
expect ( spyCoreExportVariable ) . toHaveBeenCalled ( ) ;
2022-09-08 15:26:54 +02:00
expect ( spyCoreExportVariable ) . toHaveBeenCalledWith (
2023-03-09 14:49:35 +02:00
` JAVA_HOME_ ${ input . version } _ ${ (
input . architecture || 'x86'
) . toLocaleUpperCase ( ) } ` ,
2022-09-08 15:26:54 +02:00
expected . path
) ;
2021-04-05 13:02:27 +03:00
expect ( spyCoreSetOutput ) . toHaveBeenCalled ( ) ;
2023-03-09 14:49:35 +02:00
expect ( spyCoreInfo ) . toHaveBeenCalledWith (
'Trying to resolve the latest version from remote'
) ;
expect ( spyCoreInfo ) . toHaveBeenCalledWith (
` Resolved latest version as ${ expected . version } `
) ;
2021-04-05 13:02:27 +03:00
expect ( spyCoreInfo ) . toHaveBeenCalledWith ( 'Trying to download...' ) ;
2023-03-09 14:49:35 +02:00
expect ( spyCoreInfo ) . toHaveBeenCalledWith (
` Java ${ expected . version } was downloaded `
) ;
expect ( spyCoreInfo ) . toHaveBeenCalledWith (
` Setting Java ${ expected . version } as the default `
) ;
2021-04-05 13:02:27 +03:00
} ) ;
it . each ( [
[
2023-03-09 14:49:35 +02:00
{
version : '11.0.9' ,
architecture : 'x86' ,
packageType : 'jdk' ,
checkLatest : true
} ,
{ version : '11.0.9' , path : javaPathInstalled }
2022-10-10 17:47:17 -06:00
] ,
[
2023-03-09 14:49:35 +02:00
{
version : '11.0.9' ,
architecture : '' ,
packageType : 'jdk' ,
checkLatest : true
} ,
{ version : '11.0.9' , path : javaPathInstalled }
2021-04-05 13:02:27 +03:00
]
2023-03-09 14:49:35 +02:00
] ) (
'should check the latest java version for %s and resolve locally' ,
async ( input , expected ) = > {
mockJavaBase = new EmptyJavaBase ( input ) ;
mockJavaBase [ 'findInToolcache' ] = ( ) = > ( {
version : '11.0.9' ,
path : expected.path
} ) ;
await expect ( mockJavaBase . setupJava ( ) ) . resolves . toEqual ( expected ) ;
expect ( spyCoreInfo ) . toHaveBeenCalledWith (
'Trying to resolve the latest version from remote'
) ;
expect ( spyCoreInfo ) . toHaveBeenCalledWith (
` Resolved latest version as ${ expected . version } `
) ;
expect ( spyCoreInfo ) . toHaveBeenCalledWith (
` Resolved Java ${ expected . version } from tool-cache `
) ;
expect ( spyCoreInfo ) . toHaveBeenCalledWith (
` Setting Java ${ expected . version } as the default `
) ;
}
) ;
2021-04-05 13:02:27 +03:00
2026-06-29 13:19:49 +01:00
it ( 'should fail when verify-signature is enabled for unsupported distributions' , async ( ) = > {
mockJavaBase = new EmptyJavaBase ( {
version : '11' ,
architecture : 'x86' ,
packageType : 'jdk' ,
checkLatest : false ,
verifySignature : true
} ) ;
await expect ( mockJavaBase . setupJava ( ) ) . rejects . toThrow (
"Input 'verify-signature' is not supported for distribution 'Empty'."
) ;
expect ( spyTcFindAllVersions ) . not . toHaveBeenCalled ( ) ;
expect ( spyCoreAddPath ) . not . toHaveBeenCalled ( ) ;
expect ( spyCoreExportVariable ) . not . toHaveBeenCalled ( ) ;
expect ( spyCoreSetOutput ) . not . toHaveBeenCalled ( ) ;
} ) ;
2021-04-05 13:02:27 +03:00
it . each ( [
[
2023-03-09 14:49:35 +02:00
{
version : '11' ,
architecture : 'x86' ,
packageType : 'jdk' ,
checkLatest : true
} ,
{ version : actualJavaVersion , path : javaPathInstalled }
2021-04-05 13:02:27 +03:00
] ,
[
2023-03-09 14:49:35 +02:00
{
version : '11.0' ,
architecture : 'x86' ,
packageType : 'jdk' ,
checkLatest : true
} ,
{ version : actualJavaVersion , path : javaPathInstalled }
2021-04-05 13:02:27 +03:00
] ,
[
2023-03-09 14:49:35 +02:00
{
version : '11.0.x' ,
architecture : 'x86' ,
packageType : 'jdk' ,
checkLatest : true
} ,
{ version : actualJavaVersion , path : javaPathInstalled }
2022-10-10 17:47:17 -06:00
] ,
[
2023-03-09 14:49:35 +02:00
{ version : '11' , architecture : '' , packageType : 'jdk' , checkLatest : true } ,
{ version : actualJavaVersion , path : javaPathInstalled }
2021-04-05 13:02:27 +03:00
]
2023-03-09 14:49:35 +02:00
] ) (
'should check the latest java version for %s and download' ,
async ( input , expected ) = > {
mockJavaBase = new EmptyJavaBase ( input ) ;
await expect ( mockJavaBase . setupJava ( ) ) . resolves . toEqual ( expected ) ;
expect ( spyGetToolcachePath ) . toHaveBeenCalled ( ) ;
expect ( spyCoreInfo ) . toHaveBeenCalledWith (
'Trying to resolve the latest version from remote'
) ;
expect ( spyCoreInfo ) . toHaveBeenCalledWith (
` Resolved latest version as ${ actualJavaVersion } `
) ;
expect ( spyCoreInfo ) . toHaveBeenCalledWith ( 'Trying to download...' ) ;
expect ( spyCoreInfo ) . toHaveBeenCalledWith (
` Java ${ actualJavaVersion } was downloaded `
) ;
expect ( spyCoreInfo ) . toHaveBeenCalledWith (
` Setting Java ${ expected . version } as the default `
) ;
}
) ;
2021-04-05 13:02:27 +03:00
it . each ( [
2023-03-09 14:49:35 +02:00
[
{
version : '15' ,
architecture : 'x86' ,
packageType : 'jre' ,
checkLatest : false
}
] ,
[
{
version : '11.0.7' ,
architecture : 'x64' ,
packageType : 'jre' ,
checkLatest : false
}
]
2026-04-13 23:14:45 +05:30
] ) ( 'should throw an error for version not found for %s' , async input = > {
mockJavaBase = new EmptyJavaBase ( input ) ;
await expect ( mockJavaBase . setupJava ( ) ) . rejects . toThrow (
` No matching version found for SemVer ' ${ input . version } ' `
) ;
expect ( spyTcFindAllVersions ) . toHaveBeenCalled ( ) ;
expect ( spyCoreAddPath ) . not . toHaveBeenCalled ( ) ;
expect ( spyCoreExportVariable ) . not . toHaveBeenCalled ( ) ;
expect ( spyCoreSetOutput ) . not . toHaveBeenCalled ( ) ;
} ) ;
2026-07-07 18:38:57 +02:00
it ( 'should not set JAVA_HOME and PATH when setDefault is false' , async ( ) = > {
mockJavaBase = new EmptyJavaBase ( {
version : '11' ,
architecture : 'x86' ,
packageType : 'jdk' ,
checkLatest : false ,
setDefault : false
} ) ;
await expect ( mockJavaBase . setupJava ( ) ) . resolves . toEqual ( {
version : installedJavaVersion ,
path : javaPath
} ) ;
expect ( spyCoreExportVariable ) . not . toHaveBeenCalledWith (
'JAVA_HOME' ,
expect . anything ( )
) ;
expect ( spyCoreAddPath ) . not . toHaveBeenCalled ( ) ;
expect ( spyCoreExportVariable ) . toHaveBeenCalledWith (
'JAVA_HOME_11_X86' ,
javaPath
) ;
expect ( spyCoreSetOutput ) . toHaveBeenCalledWith (
'version' ,
installedJavaVersion
) ;
expect ( spyCoreSetOutput ) . toHaveBeenCalledWith ( 'path' , javaPath ) ;
expect ( spyCoreSetOutput ) . toHaveBeenCalledWith ( 'distribution' , 'Empty' ) ;
expect ( spyCoreInfo ) . toHaveBeenCalledWith (
` Installing Java ${ installedJavaVersion } (not setting as default) `
) ;
} ) ;
it ( 'should set JAVA_HOME and PATH when setDefault is true' , async ( ) = > {
mockJavaBase = new EmptyJavaBase ( {
version : '11' ,
architecture : 'x86' ,
packageType : 'jdk' ,
checkLatest : false ,
setDefault : true
} ) ;
await expect ( mockJavaBase . setupJava ( ) ) . resolves . toEqual ( {
version : installedJavaVersion ,
path : javaPath
} ) ;
expect ( spyCoreExportVariable ) . toHaveBeenCalledWith ( 'JAVA_HOME' , javaPath ) ;
expect ( spyCoreAddPath ) . toHaveBeenCalledWith ( path . join ( javaPath , 'bin' ) ) ;
expect ( spyCoreExportVariable ) . toHaveBeenCalledWith (
'JAVA_HOME_11_X86' ,
javaPath
) ;
expect ( spyCoreInfo ) . toHaveBeenCalledWith (
` Setting Java ${ installedJavaVersion } as the default `
) ;
} ) ;
it ( 'should default to setting as default when setDefault is not specified' , async ( ) = > {
mockJavaBase = new EmptyJavaBase ( {
version : '11' ,
architecture : 'x86' ,
packageType : 'jdk' ,
checkLatest : false
} ) ;
await expect ( mockJavaBase . setupJava ( ) ) . resolves . toEqual ( {
version : installedJavaVersion ,
path : javaPath
} ) ;
expect ( spyCoreExportVariable ) . toHaveBeenCalledWith ( 'JAVA_HOME' , javaPath ) ;
expect ( spyCoreAddPath ) . toHaveBeenCalledWith ( path . join ( javaPath , 'bin' ) ) ;
expect ( spyCoreInfo ) . toHaveBeenCalledWith (
` Setting Java ${ installedJavaVersion } as the default `
) ;
} ) ;
it ( 'should download and not set default when setDefault is false' , async ( ) = > {
mockJavaBase = new EmptyJavaBase ( {
version : '11' ,
architecture : 'x64' ,
packageType : 'jdk' ,
checkLatest : false ,
setDefault : false
} ) ;
await expect ( mockJavaBase . setupJava ( ) ) . resolves . toEqual ( {
version : '11.0.9' ,
path : path.join ( 'toolcache' , 'Java_Empty_jdk' , '11.0.9' , 'x64' )
} ) ;
expect ( spyCoreExportVariable ) . not . toHaveBeenCalledWith (
'JAVA_HOME' ,
expect . anything ( )
) ;
expect ( spyCoreAddPath ) . not . toHaveBeenCalled ( ) ;
expect ( spyCoreExportVariable ) . toHaveBeenCalledWith (
'JAVA_HOME_11_X64' ,
path . join ( 'toolcache' , 'Java_Empty_jdk' , '11.0.9' , 'x64' )
) ;
expect ( spyCoreSetOutput ) . toHaveBeenCalledWith ( 'version' , '11.0.9' ) ;
expect ( spyCoreSetOutput ) . toHaveBeenCalledWith (
'path' ,
path . join ( 'toolcache' , 'Java_Empty_jdk' , '11.0.9' , 'x64' )
) ;
expect ( spyCoreInfo ) . toHaveBeenCalledWith (
'Installing Java 11.0.9 (not setting as default)'
) ;
} ) ;
2021-04-05 13:02:27 +03:00
} ) ;
describe ( 'normalizeVersion' , ( ) = > {
const DummyJavaBase = JavaBase as any ;
it . each ( [
2026-07-09 15:20:59 -04:00
[ '11' , { version : '11' , stable : true , latest : false } ] ,
[ '11.0' , { version : '11.0' , stable : true , latest : false } ] ,
[ '11.0.10' , { version : '11.0.10' , stable : true , latest : false } ] ,
[ '11-ea' , { version : '11' , stable : false , latest : false } ] ,
[ '11.0.2-ea' , { version : '11.0.2' , stable : false , latest : false } ] ,
2026-07-09 17:13:41 -04:00
[ '18.0.1.1' , { version : '18.0.1+1' , stable : true , latest : false } ] ,
[ '11.0.9.1' , { version : '11.0.9+1' , stable : true , latest : false } ] ,
[ '12.0.2.1.0' , { version : '12.0.2+1.0' , stable : true , latest : false } ] ,
[ '18.0.1.1-ea' , { version : '18.0.1+1' , stable : false , latest : false } ] ,
2026-07-09 15:20:59 -04:00
[ 'latest' , { version : 'x' , stable : true , latest : true } ] ,
[ 'LATEST' , { version : 'x' , stable : true , latest : true } ] ,
[ ' Latest ' , { version : 'x' , stable : true , latest : true } ]
2021-04-05 13:02:27 +03:00
] ) ( 'normalizeVersion from %s to %s' , ( input , expected ) = > {
2023-03-09 14:49:35 +02:00
expect ( DummyJavaBase . prototype . normalizeVersion . call ( null , input ) ) . toEqual (
expected
) ;
2021-04-05 13:02:27 +03:00
} ) ;
it ( 'normalizeVersion should throw an error for non semver' , ( ) = > {
const version = '11g' ;
2023-03-09 14:49:35 +02:00
expect (
DummyJavaBase . prototype . normalizeVersion . bind ( null , version )
) . toThrow (
2021-04-05 13:02:27 +03:00
` The string ' ${ version } ' is not valid SemVer notation for a Java version. Please check README file for code snippets and more detailed information `
) ;
} ) ;
2026-07-09 17:19:16 -04:00
it . each ( [ 'latest-ea' , 'latest.1' , 'LATEST-EA' , ' latest-ea ' ] ) (
'normalizeVersion should throw a targeted error for latest combined with a qualifier (%s)' ,
version = > {
expect (
DummyJavaBase . prototype . normalizeVersion . bind ( null , version )
) . toThrow (
` The 'latest' alias resolves stable (GA) releases only and cannot be combined with '-ea' or other qualifiers (received ' ${ version } '). Use 'latest' on its own, or specify a concrete version. `
) ;
}
) ;
2021-04-05 13:02:27 +03:00
} ) ;
2026-04-13 23:14:45 +05:30
describe ( 'createVersionNotFoundError' , ( ) = > {
it ( 'should include all required fields in error message without available versions' , ( ) = > {
const mockJavaBase = new EmptyJavaBase ( {
version : '17.0.5' ,
architecture : 'x64' ,
packageType : 'jdk' ,
checkLatest : false
} ) ;
const error = ( mockJavaBase as any ) . createVersionNotFoundError ( '17.0.5' ) ;
expect ( error . message ) . toContain (
"No matching version found for SemVer '17.0.5'"
) ;
expect ( error . message ) . toContain ( 'Distribution: Empty' ) ;
expect ( error . message ) . toContain ( 'Package type: jdk' ) ;
expect ( error . message ) . toContain ( 'Architecture: x64' ) ;
} ) ;
it ( 'should include available versions when provided' , ( ) = > {
const mockJavaBase = new EmptyJavaBase ( {
version : '17.0.5' ,
architecture : 'x64' ,
packageType : 'jdk' ,
checkLatest : false
} ) ;
const availableVersions = [ '11.0.1' , '11.0.2' , '17.0.1' , '17.0.2' ] ;
const error = ( mockJavaBase as any ) . createVersionNotFoundError (
'17.0.5' ,
availableVersions
) ;
expect ( error . message ) . toContain (
"No matching version found for SemVer '17.0.5'"
) ;
expect ( error . message ) . toContain ( 'Distribution: Empty' ) ;
expect ( error . message ) . toContain ( 'Package type: jdk' ) ;
expect ( error . message ) . toContain ( 'Architecture: x64' ) ;
expect ( error . message ) . toContain (
'Available versions: 11.0.1, 11.0.2, 17.0.1, 17.0.2'
) ;
} ) ;
it ( 'should truncate available versions when there are many' , ( ) = > {
const mockJavaBase = new EmptyJavaBase ( {
version : '17.0.5' ,
architecture : 'x64' ,
packageType : 'jdk' ,
checkLatest : false
} ) ;
// Create 60 versions to test truncation
const availableVersions = Array . from ( { length : 60 } , ( _ , i ) = > ` 11.0. ${ i } ` ) ;
const error = ( mockJavaBase as any ) . createVersionNotFoundError (
'17.0.5' ,
availableVersions
) ;
expect ( error . message ) . toContain ( 'Available versions:' ) ;
expect ( error . message ) . toContain ( '...' ) ;
expect ( error . message ) . toContain ( '(showing first 50 of 60 versions' ) ;
} ) ;
it ( 'should include additional context when provided' , ( ) = > {
const mockJavaBase = new EmptyJavaBase ( {
version : '17.0.5' ,
architecture : 'x64' ,
packageType : 'jdk' ,
checkLatest : false
} ) ;
const availableVersions = [ '11.0.1' , '11.0.2' ] ;
const additionalContext = 'Platform: linux' ;
const error = ( mockJavaBase as any ) . createVersionNotFoundError (
'17.0.5' ,
availableVersions ,
additionalContext
) ;
expect ( error . message ) . toContain (
"No matching version found for SemVer '17.0.5'"
) ;
expect ( error . message ) . toContain ( 'Distribution: Empty' ) ;
expect ( error . message ) . toContain ( 'Package type: jdk' ) ;
expect ( error . message ) . toContain ( 'Architecture: x64' ) ;
expect ( error . message ) . toContain ( 'Platform: linux' ) ;
expect ( error . message ) . toContain ( 'Available versions: 11.0.1, 11.0.2' ) ;
} ) ;
} ) ;
2021-04-05 13:02:27 +03:00
describe ( 'getToolcacheVersionName' , ( ) = > {
const DummyJavaBase = JavaBase as any ;
it . each ( [
2023-03-09 14:49:35 +02:00
[ { version : '11' , stable : true } , '11' ] ,
[ { version : '11.0.2' , stable : true } , '11.0.2' ] ,
[ { version : '11.0.2+4' , stable : true } , '11.0.2-4' ] ,
[ { version : '11.0.2+4.1.2563234' , stable : true } , '11.0.2-4.1.2563234' ] ,
[ { version : '11.0' , stable : false } , '11.0-ea' ] ,
[ { version : '11.0.3' , stable : false } , '11.0.3-ea' ] ,
[ { version : '11.0.3+4' , stable : false } , '11.0.3-ea.4' ] ,
[ { version : '11.0.3+4.2.256' , stable : false } , '11.0.3-ea.4.2.256' ]
2021-04-05 13:02:27 +03:00
] ) ( 'returns correct version name for %s' , ( input , expected ) = > {
const inputVersion = input . stable ? '11' : '11-ea' ;
const mockJavaBase = new EmptyJavaBase ( {
version : inputVersion ,
packageType : 'jdk' ,
architecture : 'x64' ,
checkLatest : false
} ) ;
const actual = mockJavaBase [ 'getToolcacheVersionName' ] ( input . version ) ;
expect ( actual ) . toBe ( expected ) ;
} ) ;
} ) ;