Migrate to ESM and upgrade dependencies

This commit is contained in:
priyagupta108 2026-06-26 10:36:45 +05:30
parent 924ae3a1cd
commit 7999c2b071
59 changed files with 125164 additions and 112480 deletions

View file

@ -1,18 +1,65 @@
import * as cache from '@actions/cache';
import * as core from '@actions/core';
import * as glob from '@actions/glob';
import {jest, describe, it, expect, beforeEach, afterEach} from '@jest/globals';
import fs from 'fs';
import * as cacheRestore from '../src/cache-restore';
import * as cacheUtils from '../src/cache-utils';
import {PackageManagerInfo} from '../src/package-managers';
jest.unstable_mockModule('@actions/cache', () => ({
saveCache: jest.fn(),
restoreCache: jest.fn(),
isFeatureAvailable: jest.fn()
}));
jest.unstable_mockModule('@actions/glob', () => ({
create: jest.fn(),
hashFiles: jest.fn()
}));
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)
}));
// Import real cache-utils (with mocked @actions) before mocking it
const realCacheUtils = await import('../src/cache-utils.js');
jest.unstable_mockModule('../src/cache-utils.js', () => ({
...realCacheUtils,
getCacheDirectoryPath: jest.fn()
}));
const cache = await import('@actions/cache');
const core = await import('@actions/core');
const glob = await import('@actions/glob');
const cacheRestore = await import('../src/cache-restore.js');
const cacheUtils = await import('../src/cache-utils.js');
import type {PackageManagerInfo} from '../src/package-managers.js';
describe('restoreCache', () => {
let hashFilesSpy: jest.SpyInstance;
let getCacheDirectoryPathSpy: jest.SpyInstance;
let restoreCacheSpy: jest.SpyInstance;
let infoSpy: jest.SpyInstance;
let setOutputSpy: jest.SpyInstance;
let hashFilesSpy: jest.Mock<typeof glob.hashFiles>;
let getCacheDirectoryPathSpy: jest.Mock<
typeof cacheUtils.getCacheDirectoryPath
>;
let restoreCacheSpy: jest.Mock<typeof cache.restoreCache>;
let infoSpy: jest.Mock<typeof core.info>;
let setOutputSpy: jest.Mock<typeof core.setOutput>;
const versionSpec = '1.13.1';
const packageManager = 'default';
@ -24,11 +71,15 @@ describe('restoreCache', () => {
originalWorkspace = process.env.GITHUB_WORKSPACE;
process.env.GITHUB_WORKSPACE = '/test/workspace';
//Arrange
hashFilesSpy = jest.spyOn(glob, 'hashFiles');
getCacheDirectoryPathSpy = jest.spyOn(cacheUtils, 'getCacheDirectoryPath');
restoreCacheSpy = jest.spyOn(cache, 'restoreCache');
infoSpy = jest.spyOn(core, 'info');
setOutputSpy = jest.spyOn(core, 'setOutput');
hashFilesSpy = glob.hashFiles as jest.Mock<typeof glob.hashFiles>;
getCacheDirectoryPathSpy = cacheUtils.getCacheDirectoryPath as jest.Mock<
typeof cacheUtils.getCacheDirectoryPath
>;
restoreCacheSpy = cache.restoreCache as jest.Mock<
typeof cache.restoreCache
>;
infoSpy = core.info as jest.Mock<typeof core.info>;
setOutputSpy = core.setOutput as jest.Mock<typeof core.setOutput>;
getCacheDirectoryPathSpy.mockImplementation(
(PackageManager: PackageManagerInfo) => {

View file

@ -1,10 +1,41 @@
import * as cache from '@actions/cache';
import * as core from '@actions/core';
import fs from 'fs';
import {jest, describe, it, expect, beforeEach, afterEach} from '@jest/globals';
import {run} from '../src/cache-save';
import * as cacheUtils from '../src/cache-utils';
import {State} from '../src/constants';
jest.unstable_mockModule('@actions/cache', () => ({
saveCache: jest.fn(),
restoreCache: jest.fn(),
isFeatureAvailable: jest.fn()
}));
jest.unstable_mockModule('@actions/core', () => ({
info: jest.fn(),
warning: jest.fn(),
debug: jest.fn(),
error: jest.fn(),
setFailed: jest.fn(),
getInput: jest.fn(),
getBooleanInput: jest.fn(),
getState: jest.fn(),
saveState: jest.fn()
}));
const realFs = (await import('fs')).default;
const fsExports = {...realFs, existsSync: jest.fn()};
jest.unstable_mockModule('fs', () => ({...fsExports, default: fsExports}));
// Import real cache-utils (with mocked @actions) before mocking it
const realCacheUtils = await import('../src/cache-utils.js');
jest.unstable_mockModule('../src/cache-utils.js', () => ({
...realCacheUtils,
getCacheDirectoryPath: jest.fn()
}));
const cache = await import('@actions/cache');
const core = await import('@actions/core');
const fs = (await import('fs')).default;
const cacheUtils = await import('../src/cache-utils.js');
const {run} = await import('../src/cache-save.js');
const {State} = await import('../src/constants.js');
describe('cache-save', () => {
const primaryKey = 'primary-key';
@ -12,24 +43,28 @@ describe('cache-save', () => {
let primaryKeyValue: string;
let matchedKeyValue: string;
let getBooleanInputSpy: jest.SpyInstance;
let getStateSpy: jest.SpyInstance;
let infoSpy: jest.SpyInstance;
let warningSpy: jest.SpyInstance;
let debugSpy: jest.SpyInstance;
let setFailedSpy: jest.SpyInstance;
let saveCacheSpy: jest.SpyInstance;
let getCacheDirectoryPathSpy: jest.SpyInstance;
let existsSpy: jest.SpyInstance;
let getBooleanInputSpy: jest.Mock<typeof core.getBooleanInput>;
let getStateSpy: jest.Mock<typeof core.getState>;
let infoSpy: jest.Mock<typeof core.info>;
let warningSpy: jest.Mock<typeof core.warning>;
let debugSpy: jest.Mock<typeof core.debug>;
let setFailedSpy: jest.Mock<typeof core.setFailed>;
let saveCacheSpy: jest.Mock<typeof cache.saveCache>;
let getCacheDirectoryPathSpy: jest.Mock<
typeof cacheUtils.getCacheDirectoryPath
>;
let existsSpy: jest.Mock<typeof fs.existsSync>;
beforeEach(() => {
primaryKeyValue = primaryKey;
matchedKeyValue = 'matched-key';
getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput');
getBooleanInputSpy = core.getBooleanInput as jest.Mock<
typeof core.getBooleanInput
>;
getBooleanInputSpy.mockReturnValue(true);
getStateSpy = jest.spyOn(core, 'getState');
getStateSpy = core.getState as jest.Mock<typeof core.getState>;
getStateSpy.mockImplementation((key: string) => {
if (key === State.CachePrimaryKey) {
return primaryKeyValue;
@ -40,32 +75,34 @@ describe('cache-save', () => {
return '';
});
infoSpy = jest.spyOn(core, 'info');
infoSpy = core.info as jest.Mock<typeof core.info>;
infoSpy.mockImplementation(() => undefined);
warningSpy = jest.spyOn(core, 'warning');
warningSpy = core.warning as jest.Mock<typeof core.warning>;
warningSpy.mockImplementation(() => undefined);
debugSpy = jest.spyOn(core, 'debug');
debugSpy = core.debug as jest.Mock<typeof core.debug>;
debugSpy.mockImplementation(() => undefined);
setFailedSpy = jest.spyOn(core, 'setFailed');
setFailedSpy = core.setFailed as jest.Mock<typeof core.setFailed>;
setFailedSpy.mockImplementation(() => undefined);
saveCacheSpy = jest.spyOn(cache, 'saveCache');
saveCacheSpy = cache.saveCache as jest.Mock<typeof cache.saveCache>;
saveCacheSpy.mockImplementation(() => Promise.resolve(0));
getCacheDirectoryPathSpy = jest.spyOn(cacheUtils, 'getCacheDirectoryPath');
getCacheDirectoryPathSpy = cacheUtils.getCacheDirectoryPath as jest.Mock<
typeof cacheUtils.getCacheDirectoryPath
>;
getCacheDirectoryPathSpy.mockImplementation(() =>
Promise.resolve(['cache_directory_path', 'cache_directory_path'])
);
existsSpy = jest.spyOn(fs, 'existsSync');
existsSpy = fs.existsSync as jest.Mock<typeof fs.existsSync>;
existsSpy.mockImplementation(() => true);
});
afterEach(() => {
jest.restoreAllMocks();
jest.clearAllMocks();
});
it('does not save cache when the cache input is false', async () => {

View file

@ -1,22 +1,60 @@
import * as exec from '@actions/exec';
import * as cache from '@actions/cache';
import * as core from '@actions/core';
import * as cacheUtils from '../src/cache-utils';
import {PackageManagerInfo} from '../src/package-managers';
import {jest, describe, it, expect, beforeEach, afterAll} from '@jest/globals';
jest.unstable_mockModule('@actions/exec', () => ({
exec: jest.fn(),
getExecOutput: jest.fn()
}));
jest.unstable_mockModule('@actions/cache', () => ({
saveCache: jest.fn(),
restoreCache: jest.fn(),
isFeatureAvailable: jest.fn()
}));
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)
}));
const exec = await import('@actions/exec');
const cache = await import('@actions/cache');
const core = await import('@actions/core');
const cacheUtils = await import('../src/cache-utils.js');
import type {PackageManagerInfo} from '../src/package-managers.js';
describe('getCommandOutput', () => {
//Arrange
const getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
const getExecOutputSpy = exec.getExecOutput as jest.Mock<
typeof exec.getExecOutput
>;
it('should return trimmed stdout in case of successful exit code', async () => {
//Arrange
const stdoutResult = ' stdout ';
const trimmedStdout = stdoutResult.trim();
getExecOutputSpy.mockImplementation((commandLine: string) => {
return new Promise<exec.ExecOutput>(resolve => {
resolve({exitCode: 0, stdout: stdoutResult, stderr: ''});
});
getExecOutputSpy.mockImplementation(async (commandLine: string) => {
return {exitCode: 0, stdout: stdoutResult, stderr: ''};
});
//Act + Assert
@ -29,10 +67,8 @@ describe('getCommandOutput', () => {
//Arrange
const stderrResult = 'error message';
getExecOutputSpy.mockImplementation((commandLine: string) => {
return new Promise<exec.ExecOutput>(resolve => {
resolve({exitCode: 10, stdout: '', stderr: stderrResult});
});
getExecOutputSpy.mockImplementation(async (commandLine: string) => {
return {exitCode: 10, stdout: '', stderr: stderrResult};
});
//Act + Assert
@ -70,7 +106,9 @@ describe('getPackageManagerInfo', () => {
describe('getCacheDirectoryPath', () => {
//Arrange
const getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
const getExecOutputSpy = exec.getExecOutput as jest.Mock<
typeof exec.getExecOutput
>;
const validPackageManager: PackageManagerInfo = {
dependencyFilePattern: 'go.mod',
@ -79,10 +117,8 @@ describe('getCacheDirectoryPath', () => {
it('should return path to the cache folders which specified package manager uses', async () => {
//Arrange
getExecOutputSpy.mockImplementation((commandLine: string) => {
return new Promise<exec.ExecOutput>(resolve => {
resolve({exitCode: 0, stdout: 'path/to/cache/folder', stderr: ''});
});
getExecOutputSpy.mockImplementation(async (commandLine: string) => {
return {exitCode: 0, stdout: 'path/to/cache/folder', stderr: ''};
});
const expectedResult = ['path/to/cache/folder', 'path/to/cache/folder'];
@ -95,16 +131,12 @@ describe('getCacheDirectoryPath', () => {
it('should return path to the cache folder if one command return empty str', async () => {
//Arrange
getExecOutputSpy.mockImplementationOnce((commandLine: string) => {
return new Promise<exec.ExecOutput>(resolve => {
resolve({exitCode: 0, stdout: 'path/to/cache/folder', stderr: ''});
});
getExecOutputSpy.mockImplementationOnce(async (commandLine: string) => {
return {exitCode: 0, stdout: 'path/to/cache/folder', stderr: ''};
});
getExecOutputSpy.mockImplementationOnce((commandLine: string) => {
return new Promise<exec.ExecOutput>(resolve => {
resolve({exitCode: 0, stdout: '', stderr: ''});
});
getExecOutputSpy.mockImplementationOnce(async (commandLine: string) => {
return {exitCode: 0, stdout: '', stderr: ''};
});
const expectedResult = ['path/to/cache/folder'];
@ -116,10 +148,8 @@ describe('getCacheDirectoryPath', () => {
});
it('should throw if the both commands return empty str', async () => {
getExecOutputSpy.mockImplementation((commandLine: string) => {
return new Promise<exec.ExecOutput>(resolve => {
resolve({exitCode: 10, stdout: '', stderr: ''});
});
getExecOutputSpy.mockImplementation(async (commandLine: string) => {
return {exitCode: 10, stdout: '', stderr: ''};
});
//Act + Assert
@ -129,10 +159,8 @@ describe('getCacheDirectoryPath', () => {
});
it('should throw if the specified package name is invalid', async () => {
getExecOutputSpy.mockImplementation((commandLine: string) => {
return new Promise<exec.ExecOutput>(resolve => {
resolve({exitCode: 10, stdout: '', stderr: 'Error message'});
});
getExecOutputSpy.mockImplementation(async (commandLine: string) => {
return {exitCode: 10, stdout: '', stderr: 'Error message'};
});
//Act + Assert
@ -144,8 +172,10 @@ describe('getCacheDirectoryPath', () => {
describe('isCacheFeatureAvailable', () => {
//Arrange
const isFeatureAvailableSpy = jest.spyOn(cache, 'isFeatureAvailable');
const warningSpy = jest.spyOn(core, 'warning');
const isFeatureAvailableSpy = cache.isFeatureAvailable as jest.Mock<
typeof cache.isFeatureAvailable
>;
const warningSpy = core.warning as jest.Mock<typeof core.warning>;
it('should return true when cache feature is available', () => {
//Arrange
@ -211,10 +241,9 @@ describe('isCacheFeatureAvailable', () => {
});
describe('isGhes', () => {
const pristineEnv = process.env;
const pristineEnv = {...process.env};
beforeEach(() => {
jest.resetModules();
process.env = {...pristineEnv};
});

View file

@ -1,17 +1,98 @@
import * as core from '@actions/core';
import * as io from '@actions/io';
import * as tc from '@actions/tool-cache';
import {
jest,
describe,
it,
expect,
beforeAll,
beforeEach,
afterEach,
afterAll
} from '@jest/globals';
import fs from 'fs';
import cp from 'child_process';
import osm, {type} from 'os';
import path from 'path';
import * as main from '../src/main';
import * as im from '../src/installer';
import * as httpm from '@actions/http-client';
import goJsonData from './data/golang-dl.json';
import matchers from '../matchers.json';
import goTestManifest from './data/versions-manifest.json';
import goJsonData from './data/golang-dl.json' with {type: 'json'};
import matchers from '../matchers.json' with {type: 'json'};
import goTestManifest from './data/versions-manifest.json' with {type: 'json'};
import type {IGoVersion} from '../src/installer.js';
import type {IToolRelease} from '@actions/tool-cache';
const httpClientGetJson = jest.fn();
const realCore = await import('@actions/core');
jest.unstable_mockModule('@actions/core', () => ({
...realCore,
getInput: jest.fn(),
getBooleanInput: jest.fn(),
info: jest.fn(),
debug: jest.fn(),
exportVariable: jest.fn()
}));
const realOs = (await import('os')).default;
const osPlatformMock = jest.fn();
const osArchMock = jest.fn();
const osExports = {
...realOs,
platform: osPlatformMock,
arch: osArchMock
};
jest.unstable_mockModule('os', () => ({...osExports, default: osExports}));
const realPath = (await import('path')).default;
const pathJoinMock = jest.fn();
const pathExports = {
...realPath,
join: pathJoinMock
};
jest.unstable_mockModule('path', () => ({
...pathExports,
default: pathExports
}));
jest.unstable_mockModule('@actions/io', () => ({
which: jest.fn(),
mkdirP: jest.fn(),
rmRF: jest.fn(),
mv: jest.fn(),
cp: jest.fn()
}));
const realTc = await import('@actions/tool-cache');
jest.unstable_mockModule('@actions/tool-cache', () => ({
...realTc,
find: jest.fn(),
downloadTool: jest.fn(),
extractTar: jest.fn(),
extractZip: jest.fn(),
cacheDir: jest.fn(),
getManifestFromRepo: jest.fn()
}));
const realHttp = await import('@actions/http-client');
jest.unstable_mockModule('@actions/http-client', () => ({
...realHttp,
HttpClient: jest.fn().mockImplementation(() => ({
getJson: httpClientGetJson
}))
}));
jest.unstable_mockModule('../src/go-version-fetch.js', () => ({
getVersionsDist: jest.fn()
}));
const core = await import('@actions/core');
const io = await import('@actions/io');
const tc = await import('@actions/tool-cache');
const vf = await import('../src/go-version-fetch.js');
const main = await import('../src/main.js');
const im = await import('../src/installer.js');
const osm = (await import('os')).default;
const path = (await import('path')).default;
const matcherPattern = matchers.problemMatcher[0].pattern[0];
const matcherRegExp = new RegExp(matcherPattern.regexp);
const win32Join = path.win32.join;
@ -23,32 +104,31 @@ describe('setup-go', () => {
let inputs = {} as any;
let os = {} as any;
let inSpy: jest.SpyInstance;
let getBooleanInputSpy: jest.SpyInstance;
let exportVarSpy: jest.SpyInstance;
let findSpy: jest.SpyInstance;
let cnSpy: jest.SpyInstance;
let logSpy: jest.SpyInstance;
let getSpy: jest.SpyInstance;
let platSpy: jest.SpyInstance;
let archSpy: jest.SpyInstance;
let joinSpy: jest.SpyInstance;
let dlSpy: jest.SpyInstance;
let extractTarSpy: jest.SpyInstance;
let extractZipSpy: jest.SpyInstance;
let cacheSpy: jest.SpyInstance;
let dbgSpy: jest.SpyInstance;
let whichSpy: jest.SpyInstance;
let existsSpy: jest.SpyInstance;
let readFileSpy: jest.SpyInstance;
let mkdirpSpy: jest.SpyInstance;
let mkdirSpy: jest.SpyInstance;
let symlinkSpy: jest.SpyInstance;
let execSpy: jest.SpyInstance;
let execFileSpy: jest.SpyInstance;
let getManifestSpy: jest.SpyInstance;
let getAllVersionsSpy: jest.SpyInstance;
let httpmGetJsonSpy: jest.SpyInstance;
let inSpy: jest.Mock<typeof core.getInput>;
let getBooleanInputSpy: jest.Mock<typeof core.getBooleanInput>;
let exportVarSpy: jest.Mock<typeof core.exportVariable>;
let findSpy: jest.Mock;
let cnSpy: jest.SpiedFunction<typeof process.stdout.write>;
let logSpy: jest.Mock;
let getSpy: jest.Mock;
let platSpy: jest.Mock;
let archSpy: jest.Mock;
let joinSpy: jest.Mock<typeof path.join>;
let dlSpy: jest.Mock;
let extractTarSpy: jest.Mock;
let extractZipSpy: jest.Mock;
let cacheSpy: jest.Mock;
let dbgSpy: jest.Mock;
let whichSpy: jest.Mock;
let existsSpy: jest.SpiedFunction<typeof fs.existsSync>;
let readFileSpy: jest.SpiedFunction<typeof fs.readFileSync>;
let mkdirpSpy: jest.Mock;
let mkdirSpy: jest.SpiedFunction<typeof fs.mkdir>;
let symlinkSpy: jest.SpiedFunction<typeof fs.symlinkSync>;
let execSpy: jest.SpiedFunction<typeof cp.execSync>;
let execFileSpy: jest.SpiedFunction<typeof cp.execFileSync>;
let getManifestSpy: jest.Mock;
let httpmGetJsonSpy: jest.Mock;
beforeAll(async () => {
process.env['GITHUB_ENV'] = ''; // Stub out Environment file functionality so we can verify it writes to standard out (toolkit is backwards compatible)
@ -59,17 +139,19 @@ describe('setup-go', () => {
// @actions/core
inputs = {};
inSpy = jest.spyOn(core, 'getInput');
inSpy = core.getInput as jest.Mock<typeof core.getInput>;
inSpy.mockImplementation(name => inputs[name]);
getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput');
getBooleanInputSpy = core.getBooleanInput as jest.Mock<
typeof core.getBooleanInput
>;
getBooleanInputSpy.mockImplementation(name => inputs[name]);
exportVarSpy = jest.spyOn(core, 'exportVariable');
exportVarSpy = core.exportVariable as jest.Mock<typeof core.exportVariable>;
// node
os = {};
platSpy = jest.spyOn(osm, 'platform');
platSpy = osm.platform as jest.Mock;
platSpy.mockImplementation(() => os['platform']);
archSpy = jest.spyOn(osm, 'arch');
archSpy = osm.arch as jest.Mock;
archSpy.mockImplementation(() => os['arch']);
execSpy = jest.spyOn(cp, 'execSync');
execFileSpy = jest.spyOn(cp, 'execFileSync');
@ -78,7 +160,7 @@ describe('setup-go', () => {
});
// switch path join behaviour based on set os.platform
joinSpy = jest.spyOn(path, 'join');
joinSpy = path.join as jest.Mock<typeof path.join>;
joinSpy.mockImplementation((...paths: string[]): string => {
if (os['platform'] == 'win32') {
return win32Join(...paths);
@ -88,23 +170,22 @@ describe('setup-go', () => {
});
// @actions/tool-cache
findSpy = jest.spyOn(tc, 'find');
dlSpy = jest.spyOn(tc, 'downloadTool');
extractTarSpy = jest.spyOn(tc, 'extractTar');
extractZipSpy = jest.spyOn(tc, 'extractZip');
cacheSpy = jest.spyOn(tc, 'cacheDir');
getSpy = jest.spyOn(im, 'getVersionsDist');
getManifestSpy = jest.spyOn(tc, 'getManifestFromRepo');
getAllVersionsSpy = jest.spyOn(im, 'getManifest');
findSpy = tc.find as jest.Mock;
dlSpy = tc.downloadTool as jest.Mock;
extractTarSpy = tc.extractTar as jest.Mock;
extractZipSpy = tc.extractZip as jest.Mock;
cacheSpy = tc.cacheDir as jest.Mock;
getSpy = vf.getVersionsDist as jest.Mock;
getManifestSpy = tc.getManifestFromRepo as jest.Mock;
// httm
httpmGetJsonSpy = jest.spyOn(httpm.HttpClient.prototype, 'getJson');
httpmGetJsonSpy = httpClientGetJson;
// io
whichSpy = jest.spyOn(io, 'which');
whichSpy = io.which as jest.Mock;
existsSpy = jest.spyOn(fs, 'existsSync');
readFileSpy = jest.spyOn(fs, 'readFileSync');
mkdirpSpy = jest.spyOn(io, 'mkdirP');
mkdirpSpy = io.mkdirP as jest.Mock;
// fs
mkdirSpy = jest.spyOn(fs, 'mkdir');
@ -112,25 +193,16 @@ describe('setup-go', () => {
symlinkSpy.mockImplementation(() => {});
// gets
getManifestSpy.mockImplementation(() => <tc.IToolRelease[]>goTestManifest);
getManifestSpy.mockImplementation(() => goTestManifest as IToolRelease[]);
// writes
cnSpy = jest.spyOn(process.stdout, 'write');
logSpy = jest.spyOn(core, 'info');
dbgSpy = jest.spyOn(core, 'debug');
getSpy.mockImplementation(() => <im.IGoVersion[] | null>goJsonData);
cnSpy.mockImplementation(line => {
// uncomment to debug
// process.stderr.write('write:' + line + '\n');
});
logSpy.mockImplementation(line => {
// uncomment to debug
//process.stderr.write('log:' + line + '\n');
});
dbgSpy.mockImplementation(msg => {
// uncomment to see debug output
// process.stderr.write(msg + '\n');
});
logSpy = core.info as jest.Mock;
dbgSpy = core.debug as jest.Mock;
getSpy.mockImplementation(() => goJsonData as IGoVersion[] | null);
cnSpy.mockImplementation(() => true);
logSpy.mockImplementation(() => {});
dbgSpy.mockImplementation(() => {});
});
afterEach(() => {
@ -138,6 +210,10 @@ describe('setup-go', () => {
delete process.env[im.GOTOOLCHAIN_ENV_VAR];
delete process.env['GO_DOWNLOAD_BASE_URL'];
// reset the exit code that core.setFailed sets on the error-path tests so
// that a passing run does not leak a non-zero process exit code
process.exitCode = 0;
//jest.resetAllMocks();
jest.clearAllMocks();
//jest.restoreAllMocks();
@ -171,8 +247,10 @@ describe('setup-go', () => {
});
it('should return manifest from raw URL if repo fetch fails', async () => {
getManifestSpy.mockRejectedValue(new Error('Fetch failed'));
httpmGetJsonSpy.mockResolvedValue({
(getManifestSpy as jest.Mock<any>).mockRejectedValue(
new Error('Fetch failed')
);
(httpmGetJsonSpy as jest.Mock<any>).mockResolvedValue({
result: goTestManifest
});
const manifest = await im.getManifest(undefined);
@ -211,7 +289,7 @@ describe('setup-go', () => {
os.arch = 'x64';
// spec: 1.13.0 => 1.13
const match: im.IGoVersion | undefined = await im.findMatch('1.13.0');
const match: IGoVersion | undefined = await im.findMatch('1.13.0');
expect(match).toBeDefined();
const version: string = match ? match.version : '';
expect(version).toBe('go1.13');
@ -224,7 +302,7 @@ describe('setup-go', () => {
os.arch = 'x64';
// spec: 1.13 => 1.13.7 (latest)
const match: im.IGoVersion | undefined = await im.findMatch('1.13');
const match: IGoVersion | undefined = await im.findMatch('1.13');
expect(match).toBeDefined();
const version: string = match ? match.version : '';
expect(version).toBe('go1.13.7');
@ -237,7 +315,7 @@ describe('setup-go', () => {
os.arch = 'x64';
// spec: ^1.13.6 => 1.13.7
const match: im.IGoVersion | undefined = await im.findMatch('^1.13.6');
const match: IGoVersion | undefined = await im.findMatch('^1.13.6');
expect(match).toBeDefined();
const version: string = match ? match.version : '';
expect(version).toBe('go1.13.7');
@ -250,7 +328,7 @@ describe('setup-go', () => {
os.arch = 'x32';
// spec: 1 => 1.13.7 (latest)
const match: im.IGoVersion | undefined = await im.findMatch('1');
const match: IGoVersion | undefined = await im.findMatch('1');
expect(match).toBeDefined();
const version: string = match ? match.version : '';
expect(version).toBe('go1.13.7');
@ -263,7 +341,7 @@ describe('setup-go', () => {
os.arch = 'x64';
// spec: 1.14, stable=false => go1.14rc1
const match: im.IGoVersion | undefined = await im.findMatch('1.14.0-rc.1');
const match: IGoVersion | undefined = await im.findMatch('1.14.0-rc.1');
expect(match).toBeDefined();
const version: string = match ? match.version : '';
expect(version).toBe('go1.14rc1');
@ -817,10 +895,9 @@ describe('setup-go', () => {
getManifestSpy.mockImplementation(() => {
throw new Error('Unable to download manifest');
});
httpmGetJsonSpy.mockRejectedValue(
(httpmGetJsonSpy as jest.Mock<any>).mockRejectedValue(
new Error('Unable to download manifest from raw URL')
);
getAllVersionsSpy.mockImplementationOnce(() => undefined);
dlSpy.mockImplementation(async () => '/some/temp/path');
const toolPath = path.normalize('/cache/go/1.13.7/x64');

View file

@ -1,4 +1,5 @@
import {isSelfHosted} from '../src/utils';
import {describe, it, expect, beforeEach, afterEach} from '@jest/globals';
import {isSelfHosted} from '../src/utils.js';
describe('utils', () => {
describe('isSelfHosted', () => {

View file

@ -1,38 +1,57 @@
import fs from 'fs';
import * as io from '@actions/io';
import * as tc from '@actions/tool-cache';
import {jest, describe, it, expect, beforeEach, afterEach} from '@jest/globals';
import path from 'path';
const statSyncMock = jest.fn(() => ({
isDirectory: () => true,
isFile: () => true
}));
const readdirSyncMock = jest.fn(() => [] as any);
const writeFileSyncMock = jest.fn();
const mkdirMock = jest.fn();
const symlinkSyncMock = jest.fn();
jest.unstable_mockModule('@actions/io', () => ({
which: jest.fn(),
mkdirP: jest.fn(() => Promise.resolve()),
rmRF: jest.fn(() => Promise.resolve()),
mv: jest.fn(() => Promise.resolve()),
cp: jest.fn(() => Promise.resolve())
}));
const realFs = (await import('fs')).default;
const fsExports = {
...realFs,
statSync: statSyncMock,
readdirSync: readdirSyncMock,
writeFileSync: writeFileSyncMock,
mkdir: mkdirMock,
symlinkSync: symlinkSyncMock
};
jest.unstable_mockModule('fs', () => ({...fsExports, default: fsExports}));
const io = await import('@actions/io');
const tc = await import('@actions/tool-cache');
describe('Windows performance workaround', () => {
let mkdirSpy: jest.SpyInstance;
let symlinkSpy: jest.SpyInstance;
let statSpy: jest.SpyInstance;
let readdirSpy: jest.SpyInstance;
let writeFileSpy: jest.SpyInstance;
let rmRFSpy: jest.SpyInstance;
let mkdirPSpy: jest.SpyInstance;
let cpSpy: jest.SpyInstance;
let rmRFSpy: jest.Mock;
let mkdirPSpy: jest.Mock;
let cpSpy: jest.Mock;
let runnerToolCache: string | undefined;
beforeEach(() => {
mkdirSpy = jest.spyOn(fs, 'mkdir');
symlinkSpy = jest.spyOn(fs, 'symlinkSync');
statSpy = jest.spyOn(fs, 'statSync');
readdirSpy = jest.spyOn(fs, 'readdirSync');
writeFileSpy = jest.spyOn(fs, 'writeFileSync');
rmRFSpy = jest.spyOn(io, 'rmRF');
mkdirPSpy = jest.spyOn(io, 'mkdirP');
cpSpy = jest.spyOn(io, 'cp');
rmRFSpy = io.rmRF as jest.Mock;
mkdirPSpy = io.mkdirP as jest.Mock;
cpSpy = io.cp as jest.Mock;
// default implementations
// @ts-ignore - not implement unused methods
statSpy.mockImplementation(() => ({
isDirectory: () => true
statSyncMock.mockImplementation(() => ({
isDirectory: () => true,
isFile: () => true
}));
readdirSpy.mockImplementation(() => []);
writeFileSpy.mockImplementation(() => {});
mkdirSpy.mockImplementation(() => {});
symlinkSpy.mockImplementation(() => {});
readdirSyncMock.mockImplementation(() => []);
writeFileSyncMock.mockImplementation(() => {});
mkdirMock.mockImplementation(() => {});
symlinkSyncMock.mockImplementation(() => {});
rmRFSpy.mockImplementation(() => Promise.resolve());
mkdirPSpy.mockImplementation(() => Promise.resolve());
cpSpy.mockImplementation(() => Promise.resolve());