Read-only mirror — the public repositories of the Forgejo instance, refreshed every 10 minutes. The live instance (fg.dieschoenewolke.de) is reachable only over the VPN; clone here with https://git.dieschoenewolke.de/git/<owner>/<repo>.git.
summaryrefslogtreecommitdiff
path: root/__test__
diff options
context:
space:
mode:
authorAiqiao Yan <55104035+aiqiaoy@users.noreply.github.com>2026-06-16 17:10:58 -0400
committerGitHub <noreply@github.com>2026-06-16 17:10:58 -0400
commitc68c2101c254470055e8aa38730553d71a47bc7b (patch)
tree3d9a1c982fc2d3aed23e80a58d221942ac249155 /__test__
parent6e97fb5586f435ba4f325b363a1c7329470cebf6 (diff)
upgrade module to esm and update dependencies (#2463)
* upgrade module to esm so I can update dependencies * fix ci failures
Diffstat (limited to '__test__')
-rw-r--r--__test__/git-auth-helper.test.ts75
-rw-r--r--__test__/git-command-manager.test.ts105
-rw-r--r--__test__/git-directory-helper.test.ts60
-rw-r--r--__test__/git-version.test.ts5
-rw-r--r--__test__/github-api-helper.test.ts44
-rw-r--r--__test__/input-helper.test.ts119
-rw-r--r--__test__/ref-helper.test.ts92
-rw-r--r--__test__/retry-helper.test.ts33
-rw-r--r--__test__/unsafe-pr-checkout-helper.test.ts56
-rw-r--r--__test__/url-helper.test.ts3
10 files changed, 378 insertions, 214 deletions
diff --git a/__test__/git-auth-helper.test.ts b/__test__/git-auth-helper.test.ts
index 3c4f049..2c963b9 100644
--- a/__test__/git-auth-helper.test.ts
+++ b/__test__/git-auth-helper.test.ts
@@ -1,12 +1,46 @@
-import * as core from '@actions/core'
+import {
+ jest,
+ describe,
+ it,
+ expect,
+ beforeAll,
+ beforeEach,
+ afterEach,
+ afterAll
+} from '@jest/globals'
import * as fs from 'fs'
-import * as gitAuthHelper from '../lib/git-auth-helper'
import * as io from '@actions/io'
import * as os from 'os'
import * as path from 'path'
-import * as stateHelper from '../lib/state-helper'
-import {IGitCommandManager} from '../lib/git-command-manager'
-import {IGitSourceSettings} from '../lib/git-source-settings'
+import {fileURLToPath} from 'url'
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url))
+
+// Mock @actions/core before loading git-auth-helper
+jest.unstable_mockModule('@actions/core', () => ({
+ setSecret: jest.fn(),
+ error: jest.fn(),
+ warning: jest.fn(),
+ info: jest.fn(),
+ debug: jest.fn(),
+ setFailed: jest.fn()
+}))
+
+// Mock state-helper
+jest.unstable_mockModule('../src/state-helper.js', () => ({
+ setSshKeyPath: jest.fn(),
+ setSshKnownHostsPath: jest.fn(),
+ IsPost: false,
+ RepositoryPath: ''
+}))
+
+// Dynamic imports after mocking
+const core = await import('@actions/core')
+const gitAuthHelper = await import('../src/git-auth-helper.js')
+type IGitCommandManager =
+ import('../src/git-command-manager.js').IGitCommandManager
+type IGitSourceSettings =
+ import('../src/git-source-settings.js').IGitSourceSettings
const isWindows = process.platform === 'win32'
const testWorkspace = path.join(__dirname, '_temp', 'git-auth-helper')
@@ -32,25 +66,12 @@ describe('git-auth-helper tests', () => {
})
beforeEach(() => {
- // Mock setSecret
- jest.spyOn(core, 'setSecret').mockImplementation((secret: string) => {})
-
- // Mock error/warning/info/debug
- jest.spyOn(core, 'error').mockImplementation(jest.fn())
- jest.spyOn(core, 'warning').mockImplementation(jest.fn())
- jest.spyOn(core, 'info').mockImplementation(jest.fn())
- jest.spyOn(core, 'debug').mockImplementation(jest.fn())
-
- // Mock state helper
- jest.spyOn(stateHelper, 'setSshKeyPath').mockImplementation(jest.fn())
- jest
- .spyOn(stateHelper, 'setSshKnownHostsPath')
- .mockImplementation(jest.fn())
+ jest.clearAllMocks()
})
afterEach(() => {
// Unregister mocks
- jest.restoreAllMocks()
+ jest.clearAllMocks()
// Restore HOME
if (originalHome) {
@@ -229,7 +250,7 @@ describe('git-auth-helper tests', () => {
await authHelper.configureAuth()
// Assert secret
- const setSecretSpy = core.setSecret as jest.Mock<any, any>
+ const setSecretSpy = core.setSecret as jest.Mock<any>
expect(setSecretSpy).toHaveBeenCalledTimes(1)
const expectedSecret = Buffer.from(
`x-access-token:${settings.authToken}`,
@@ -529,7 +550,7 @@ describe('git-auth-helper tests', () => {
settings.sshKey = ''
const authHelper = gitAuthHelper.createAuthHelper(git, settings)
await authHelper.configureAuth()
- const mockSubmoduleForeach = git.submoduleForeach as jest.Mock<any, any>
+ const mockSubmoduleForeach = git.submoduleForeach as jest.Mock<any>
mockSubmoduleForeach.mockClear() // reset calls
// Act
@@ -562,7 +583,7 @@ describe('git-auth-helper tests', () => {
settings.persistCredentials = false
const authHelper = gitAuthHelper.createAuthHelper(git, settings)
await authHelper.configureAuth()
- const mockSubmoduleForeach = git.submoduleForeach as jest.Mock<any, any>
+ const mockSubmoduleForeach = git.submoduleForeach as jest.Mock<any>
mockSubmoduleForeach.mockClear() // reset calls
// Act
@@ -588,7 +609,7 @@ describe('git-auth-helper tests', () => {
settings.sshKey = ''
const authHelper = gitAuthHelper.createAuthHelper(git, settings)
await authHelper.configureAuth()
- const mockSubmoduleForeach = git.submoduleForeach as jest.Mock<any, any>
+ const mockSubmoduleForeach = git.submoduleForeach as jest.Mock<any>
mockSubmoduleForeach.mockClear() // reset calls
// Act
@@ -627,7 +648,7 @@ describe('git-auth-helper tests', () => {
)
const authHelper = gitAuthHelper.createAuthHelper(git, settings)
await authHelper.configureAuth()
- const mockSubmoduleForeach = git.submoduleForeach as jest.Mock<any, any>
+ const mockSubmoduleForeach = git.submoduleForeach as jest.Mock<any>
mockSubmoduleForeach.mockClear() // reset calls
// Act
@@ -809,7 +830,7 @@ describe('git-auth-helper tests', () => {
// Mock getSubmoduleConfigPaths to return our fake submodules (for both configure and remove)
const mockGetSubmoduleConfigPaths =
- git.getSubmoduleConfigPaths as jest.Mock<any, any>
+ git.getSubmoduleConfigPaths as jest.Mock<any>
mockGetSubmoduleConfigPaths.mockResolvedValue([
submodule1ConfigPath,
submodule2ConfigPath
@@ -1147,7 +1168,7 @@ async function setup(testName: string): Promise<void> {
),
tryReset: jest.fn(),
version: jest.fn()
- }
+ } as unknown as IGitCommandManager & {env: {[key: string]: string}}
settings = {
authToken: 'some auth token',
diff --git a/__test__/git-command-manager.test.ts b/__test__/git-command-manager.test.ts
index 47a0f8f..e669c0f 100644
--- a/__test__/git-command-manager.test.ts
+++ b/__test__/git-command-manager.test.ts
@@ -1,26 +1,51 @@
-import * as exec from '@actions/exec'
-import * as fshelper from '../lib/fs-helper'
-import * as commandManager from '../lib/git-command-manager'
-
-let git: commandManager.IGitCommandManager
-let mockExec = jest.fn()
+import {
+ jest,
+ describe,
+ it,
+ expect,
+ beforeAll,
+ beforeEach,
+ afterEach,
+ afterAll
+} from '@jest/globals'
+
+// Mock @actions/exec
+const mockExec = jest.fn()
+jest.unstable_mockModule('@actions/exec', () => ({
+ exec: mockExec
+}))
+
+// Mock fs-helper
+const mockFileExistsSync = jest.fn()
+const mockDirectoryExistsSync = jest.fn()
+jest.unstable_mockModule('../src/fs-helper.js', () => ({
+ fileExistsSync: mockFileExistsSync,
+ directoryExistsSync: mockDirectoryExistsSync
+}))
+
+// Dynamic imports after mocking
+const commandManager = await import('../src/git-command-manager.js')
+type IGitCommandManager =
+ import('../src/git-command-manager.js').IGitCommandManager
+
+let git: IGitCommandManager
describe('git-auth-helper tests', () => {
beforeAll(async () => {})
beforeEach(async () => {
- jest.spyOn(fshelper, 'fileExistsSync').mockImplementation(jest.fn())
- jest.spyOn(fshelper, 'directoryExistsSync').mockImplementation(jest.fn())
+ mockFileExistsSync.mockReset()
+ mockDirectoryExistsSync.mockReset()
})
afterEach(() => {
- jest.restoreAllMocks()
+ jest.clearAllMocks()
})
afterAll(() => {})
it('branch list matches', async () => {
- mockExec.mockImplementation((path, args, options) => {
+ mockExec.mockImplementation((path: any, args: any, options: any) => {
console.log(args, options.listeners.stdout)
if (args.includes('version')) {
@@ -36,7 +61,7 @@ describe('git-auth-helper tests', () => {
return 1
})
- jest.spyOn(exec, 'exec').mockImplementation(mockExec)
+ // exec.exec is already mockExec
const workingDirectory = 'test'
const lfs = false
const doSparseCheckout = false
@@ -53,7 +78,7 @@ describe('git-auth-helper tests', () => {
})
it('ambiguous ref name output is captured', async () => {
- mockExec.mockImplementation((path, args, options) => {
+ mockExec.mockImplementation((path: any, args: any, options: any) => {
console.log(args, options.listeners.stdout)
if (args.includes('version')) {
@@ -72,7 +97,7 @@ describe('git-auth-helper tests', () => {
return 1
})
- jest.spyOn(exec, 'exec').mockImplementation(mockExec)
+ // exec.exec is already mockExec
const workingDirectory = 'test'
const lfs = false
const doSparseCheckout = false
@@ -91,9 +116,9 @@ describe('git-auth-helper tests', () => {
describe('Test fetchDepth and fetchTags options', () => {
beforeEach(async () => {
- jest.spyOn(fshelper, 'fileExistsSync').mockImplementation(jest.fn())
- jest.spyOn(fshelper, 'directoryExistsSync').mockImplementation(jest.fn())
- mockExec.mockImplementation((path, args, options) => {
+ mockFileExistsSync.mockReset()
+ mockDirectoryExistsSync.mockReset()
+ mockExec.mockImplementation((path: any, args: any, options: any) => {
console.log(args, options.listeners.stdout)
if (args.includes('version')) {
@@ -105,11 +130,11 @@ describe('Test fetchDepth and fetchTags options', () => {
})
afterEach(() => {
- jest.restoreAllMocks()
+ jest.clearAllMocks()
})
it('should call execGit with the correct arguments when fetchDepth is 0', async () => {
- jest.spyOn(exec, 'exec').mockImplementation(mockExec)
+ // exec.exec is already mockExec
const workingDirectory = 'test'
const lfs = false
const doSparseCheckout = false
@@ -146,7 +171,7 @@ describe('Test fetchDepth and fetchTags options', () => {
})
it('should call execGit with the correct arguments when fetchDepth is 0 and refSpec includes tags', async () => {
- jest.spyOn(exec, 'exec').mockImplementation(mockExec)
+ // exec.exec is already mockExec
const workingDirectory = 'test'
const lfs = false
@@ -184,7 +209,7 @@ describe('Test fetchDepth and fetchTags options', () => {
})
it('should call execGit with the correct arguments when fetchDepth is 1', async () => {
- jest.spyOn(exec, 'exec').mockImplementation(mockExec)
+ // exec.exec is already mockExec
const workingDirectory = 'test'
const lfs = false
@@ -222,7 +247,7 @@ describe('Test fetchDepth and fetchTags options', () => {
})
it('should call execGit with the correct arguments when fetchDepth is 1 and refSpec includes tags', async () => {
- jest.spyOn(exec, 'exec').mockImplementation(mockExec)
+ // exec.exec is already mockExec
const workingDirectory = 'test'
const lfs = false
@@ -261,7 +286,7 @@ describe('Test fetchDepth and fetchTags options', () => {
})
it('should call execGit with the correct arguments when showProgress is true', async () => {
- jest.spyOn(exec, 'exec').mockImplementation(mockExec)
+ // exec.exec is already mockExec
const workingDirectory = 'test'
const lfs = false
@@ -299,7 +324,7 @@ describe('Test fetchDepth and fetchTags options', () => {
})
it('should call execGit with the correct arguments when fetchDepth is 42 and showProgress is true', async () => {
- jest.spyOn(exec, 'exec').mockImplementation(mockExec)
+ // exec.exec is already mockExec
const workingDirectory = 'test'
const lfs = false
@@ -339,7 +364,7 @@ describe('Test fetchDepth and fetchTags options', () => {
})
it('should call execGit with the correct arguments when showProgress is true and refSpec includes tags', async () => {
- jest.spyOn(exec, 'exec').mockImplementation(mockExec)
+ // exec.exec is already mockExec
const workingDirectory = 'test'
const lfs = false
@@ -380,23 +405,23 @@ describe('Test fetchDepth and fetchTags options', () => {
describe('repository initialization object format', () => {
beforeEach(async () => {
- jest.spyOn(fshelper, 'fileExistsSync').mockImplementation(jest.fn())
- jest.spyOn(fshelper, 'directoryExistsSync').mockImplementation(jest.fn())
+ mockFileExistsSync.mockReset()
+ mockDirectoryExistsSync.mockReset()
})
afterEach(() => {
- jest.restoreAllMocks()
+ jest.clearAllMocks()
})
it('initializes SHA-256 repositories with the matching object format', async () => {
- mockExec.mockImplementation((path, args, options) => {
+ mockExec.mockImplementation((path: any, args: any, options: any) => {
if (args.includes('version')) {
options.listeners.stdout(Buffer.from('git version 2.50.1'))
}
return 0
})
- jest.spyOn(exec, 'exec').mockImplementation(mockExec)
+ // exec.exec is already mockExec
git = await commandManager.createCommandManager('test', false, false)
@@ -410,14 +435,14 @@ describe('repository initialization object format', () => {
})
it('initializes SHA-1 repositories with existing default arguments', async () => {
- mockExec.mockImplementation((path, args, options) => {
+ mockExec.mockImplementation((path: any, args: any, options: any) => {
if (args.includes('version')) {
options.listeners.stdout(Buffer.from('git version 2.50.1'))
}
return 0
})
- jest.spyOn(exec, 'exec').mockImplementation(mockExec)
+ // exec.exec is already mockExec
git = await commandManager.createCommandManager('test', false, false)
@@ -433,12 +458,12 @@ describe('repository initialization object format', () => {
describe('git user-agent with orchestration ID', () => {
beforeEach(async () => {
- jest.spyOn(fshelper, 'fileExistsSync').mockImplementation(jest.fn())
- jest.spyOn(fshelper, 'directoryExistsSync').mockImplementation(jest.fn())
+ mockFileExistsSync.mockReset()
+ mockDirectoryExistsSync.mockReset()
})
afterEach(() => {
- jest.restoreAllMocks()
+ jest.clearAllMocks()
// Clean up environment variable to prevent test pollution
delete process.env['ACTIONS_ORCHESTRATION_ID']
})
@@ -448,7 +473,7 @@ describe('git user-agent with orchestration ID', () => {
process.env['ACTIONS_ORCHESTRATION_ID'] = orchId
let capturedEnv: any = null
- mockExec.mockImplementation((path, args, options) => {
+ mockExec.mockImplementation((path: any, args: any, options: any) => {
if (args.includes('version')) {
options.listeners.stdout(Buffer.from('2.18'))
}
@@ -456,7 +481,7 @@ describe('git user-agent with orchestration ID', () => {
capturedEnv = options.env
return 0
})
- jest.spyOn(exec, 'exec').mockImplementation(mockExec)
+ // exec.exec is already mockExec
const workingDirectory = 'test'
const lfs = false
@@ -483,7 +508,7 @@ describe('git user-agent with orchestration ID', () => {
process.env['ACTIONS_ORCHESTRATION_ID'] = orchId
let capturedEnv: any = null
- mockExec.mockImplementation((path, args, options) => {
+ mockExec.mockImplementation((path: any, args: any, options: any) => {
if (args.includes('version')) {
options.listeners.stdout(Buffer.from('2.18'))
}
@@ -491,7 +516,7 @@ describe('git user-agent with orchestration ID', () => {
capturedEnv = options.env
return 0
})
- jest.spyOn(exec, 'exec').mockImplementation(mockExec)
+ // exec.exec is already mockExec
const workingDirectory = 'test'
const lfs = false
@@ -517,7 +542,7 @@ describe('git user-agent with orchestration ID', () => {
delete process.env['ACTIONS_ORCHESTRATION_ID']
let capturedEnv: any = null
- mockExec.mockImplementation((path, args, options) => {
+ mockExec.mockImplementation((path: any, args: any, options: any) => {
if (args.includes('version')) {
options.listeners.stdout(Buffer.from('2.18'))
}
@@ -525,7 +550,7 @@ describe('git user-agent with orchestration ID', () => {
capturedEnv = options.env
return 0
})
- jest.spyOn(exec, 'exec').mockImplementation(mockExec)
+ // exec.exec is already mockExec
const workingDirectory = 'test'
const lfs = false
diff --git a/__test__/git-directory-helper.test.ts b/__test__/git-directory-helper.test.ts
index de79dc8..4dd5fda 100644
--- a/__test__/git-directory-helper.test.ts
+++ b/__test__/git-directory-helper.test.ts
@@ -1,9 +1,36 @@
-import * as core from '@actions/core'
+import {
+ jest,
+ describe,
+ it,
+ expect,
+ beforeAll,
+ beforeEach,
+ afterEach
+} from '@jest/globals'
import * as fs from 'fs'
-import * as gitDirectoryHelper from '../lib/git-directory-helper'
import * as io from '@actions/io'
import * as path from 'path'
-import {IGitCommandManager} from '../lib/git-command-manager'
+import {fileURLToPath} from 'url'
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url))
+
+// Mock @actions/core before loading git-directory-helper
+jest.unstable_mockModule('@actions/core', () => ({
+ error: jest.fn(),
+ warning: jest.fn(),
+ info: jest.fn(),
+ debug: jest.fn(),
+ setFailed: jest.fn(),
+ startGroup: jest.fn(),
+ endGroup: jest.fn()
+}))
+
+// Dynamic imports after mocking
+const core = await import('@actions/core')
+const gitDirectoryHelper = await import('../src/git-directory-helper.js')
+
+type IGitCommandManager =
+ import('../src/git-command-manager.js').IGitCommandManager
const testWorkspace = path.join(__dirname, '_temp', 'git-directory-helper')
let repositoryPath: string
@@ -19,16 +46,11 @@ describe('git-directory-helper tests', () => {
})
beforeEach(() => {
- // Mock error/warning/info/debug
- jest.spyOn(core, 'error').mockImplementation(jest.fn())
- jest.spyOn(core, 'warning').mockImplementation(jest.fn())
- jest.spyOn(core, 'info').mockImplementation(jest.fn())
- jest.spyOn(core, 'debug').mockImplementation(jest.fn())
+ jest.clearAllMocks()
})
afterEach(() => {
- // Unregister mocks
- jest.restoreAllMocks()
+ jest.clearAllMocks()
})
const cleansWhenCleanTrue = 'cleans when clean true'
@@ -81,7 +103,7 @@ describe('git-directory-helper tests', () => {
// Arrange
await setup(doesNotCheckoutDetachWhenNotAlreadyDetached)
await fs.promises.writeFile(path.join(repositoryPath, 'my-file'), '')
- const mockIsDetached = git.isDetached as jest.Mock<any, any>
+ const mockIsDetached = git.isDetached as jest.Mock<any>
mockIsDetached.mockImplementation(async () => {
return true
})
@@ -132,7 +154,7 @@ describe('git-directory-helper tests', () => {
// Arrange
await setup(removesContentsWhenCleanFails)
await fs.promises.writeFile(path.join(repositoryPath, 'my-file'), '')
- let mockTryClean = git.tryClean as jest.Mock<any, any>
+ let mockTryClean = git.tryClean as jest.Mock<any>
mockTryClean.mockImplementation(async () => {
return false
})
@@ -210,7 +232,7 @@ describe('git-directory-helper tests', () => {
// Arrange
await setup(removesContentsWhenResetFails)
await fs.promises.writeFile(path.join(repositoryPath, 'my-file'), '')
- let mockTryReset = git.tryReset as jest.Mock<any, any>
+ let mockTryReset = git.tryReset as jest.Mock<any>
mockTryReset.mockImplementation(async () => {
return false
})
@@ -260,7 +282,7 @@ describe('git-directory-helper tests', () => {
// Arrange
await setup(removesLocalBranches)
await fs.promises.writeFile(path.join(repositoryPath, 'my-file'), '')
- const mockBranchList = git.branchList as jest.Mock<any, any>
+ const mockBranchList = git.branchList as jest.Mock<any>
mockBranchList.mockImplementation(async (remote: boolean) => {
return remote ? [] : ['local-branch-1', 'local-branch-2']
})
@@ -291,7 +313,7 @@ describe('git-directory-helper tests', () => {
//mock bad submodule
- const submoduleStatus = git.submoduleStatus as jest.Mock<any, any>
+ const submoduleStatus = git.submoduleStatus as jest.Mock<any>
submoduleStatus.mockImplementation(async (remote: boolean) => {
return false
})
@@ -319,7 +341,7 @@ describe('git-directory-helper tests', () => {
await setup(doesNotCleanWhenSubmoduleStatusIsTrue)
await fs.promises.writeFile(path.join(repositoryPath, 'my-file'), '')
- const submoduleStatus = git.submoduleStatus as jest.Mock<any, any>
+ const submoduleStatus = git.submoduleStatus as jest.Mock<any>
submoduleStatus.mockImplementation(async (remote: boolean) => {
return true
})
@@ -381,7 +403,7 @@ describe('git-directory-helper tests', () => {
// Arrange
await setup(removesAncestorRemoteBranch)
await fs.promises.writeFile(path.join(repositoryPath, 'my-file'), '')
- const mockBranchList = git.branchList as jest.Mock<any, any>
+ const mockBranchList = git.branchList as jest.Mock<any>
mockBranchList.mockImplementation(async (remote: boolean) => {
return remote ? ['origin/remote-branch-1', 'origin/remote-branch-2'] : []
})
@@ -411,7 +433,7 @@ describe('git-directory-helper tests', () => {
// Arrange
await setup(removesDescendantRemoteBranches)
await fs.promises.writeFile(path.join(repositoryPath, 'my-file'), '')
- const mockBranchList = git.branchList as jest.Mock<any, any>
+ const mockBranchList = git.branchList as jest.Mock<any>
mockBranchList.mockImplementation(async (remote: boolean) => {
return remote
? ['origin/remote-branch-1/conflict', 'origin/remote-branch-2']
@@ -507,5 +529,5 @@ async function setup(testName: string): Promise<void> {
return true
}),
version: jest.fn()
- }
+ } as unknown as IGitCommandManager
}
diff --git a/__test__/git-version.test.ts b/__test__/git-version.test.ts
index 27f702e..740d46e 100644
--- a/__test__/git-version.test.ts
+++ b/__test__/git-version.test.ts
@@ -1,5 +1,6 @@
-import {GitVersion} from '../src/git-version'
-import {MinimumGitSparseCheckoutVersion} from '../src/git-command-manager'
+import {describe, it, expect} from '@jest/globals'
+import {GitVersion} from '../src/git-version.js'
+import {MinimumGitSparseCheckoutVersion} from '../src/git-command-manager.js'
describe('git-version tests', () => {
it('basics', async () => {
diff --git a/__test__/github-api-helper.test.ts b/__test__/github-api-helper.test.ts
index 6319e20..3470f20 100644
--- a/__test__/github-api-helper.test.ts
+++ b/__test__/github-api-helper.test.ts
@@ -1,11 +1,25 @@
-import * as core from '@actions/core'
-import * as github from '@actions/github'
-import * as githubApiHelper from '../lib/github-api-helper'
+import {jest, describe, it, expect, beforeEach, afterEach} from '@jest/globals'
+
+// Mock @actions/core
+const mockDebug = jest.fn()
+jest.unstable_mockModule('@actions/core', () => ({
+ debug: mockDebug,
+ info: jest.fn(),
+ warning: jest.fn(),
+ error: jest.fn()
+}))
+
+// Mock @actions/github
+const mockGetOctokit = jest.fn()
+jest.unstable_mockModule('@actions/github', () => ({
+ getOctokit: mockGetOctokit
+}))
+
+// Dynamic imports after mocking
+const githubApiHelper = await import('../src/github-api-helper.js')
describe('github-api-helper object format', () => {
- let getOctokitSpy: jest.SpyInstance
- let debugSpy: jest.SpyInstance
- let request: jest.Mock
+ let request: jest.Mock<any>
function mockHashAlgorithmApi(hashAlgorithm: string): void {
request = jest.fn(async () => ({
@@ -13,17 +27,18 @@ describe('github-api-helper object format', () => {
hash_algorithm: hashAlgorithm
}
}))
- getOctokitSpy = jest.spyOn(github, 'getOctokit').mockReturnValue({
+ mockGetOctokit.mockReturnValue({
request
} as any)
}
beforeEach(() => {
- debugSpy = jest.spyOn(core, 'debug').mockImplementation(jest.fn())
+ mockDebug.mockClear()
+ mockGetOctokit.mockClear()
})
afterEach(() => {
- jest.restoreAllMocks()
+ jest.clearAllMocks()
})
it('detects SHA-256 from the repository hash algorithm endpoint', async () => {
@@ -33,7 +48,7 @@ describe('github-api-helper object format', () => {
githubApiHelper.tryGetRepositoryObjectFormat('token', 'owner', 'repo')
).resolves.toEqual({format: 'sha256', succeeded: true})
- expect(getOctokitSpy).toHaveBeenCalledWith(
+ expect(mockGetOctokit).toHaveBeenCalledWith(
'token',
expect.objectContaining({baseUrl: 'https://api.github.com'})
)
@@ -54,7 +69,6 @@ describe('github-api-helper object format', () => {
it('detects object format from an existing commit without API calls', async () => {
const commitSha =
'9422233ca7ee1b17f1e905d0e141faf0c401556c41cdc6acd71c6bd685da2e92'
- getOctokitSpy = jest.spyOn(github, 'getOctokit')
await expect(
githubApiHelper.tryGetRepositoryObjectFormat(
@@ -66,7 +80,7 @@ describe('github-api-helper object format', () => {
)
).resolves.toEqual({format: 'sha256', succeeded: true})
- expect(getOctokitSpy).not.toHaveBeenCalled()
+ expect(mockGetOctokit).not.toHaveBeenCalled()
})
it('returns unsuccessful when the hash algorithm endpoint value is not recognized', async () => {
@@ -75,7 +89,7 @@ describe('github-api-helper object format', () => {
await expect(
githubApiHelper.tryGetRepositoryObjectFormat('token', 'owner', 'repo')
).resolves.toEqual({format: '', succeeded: false})
- expect(debugSpy).toHaveBeenCalledWith(
+ expect(mockDebug).toHaveBeenCalledWith(
'Unable to determine repository object format from hash-algorithm endpoint'
)
})
@@ -84,14 +98,14 @@ describe('github-api-helper object format', () => {
request = jest.fn(async () => {
throw new Error('not found')
})
- jest.spyOn(github, 'getOctokit').mockReturnValue({
+ mockGetOctokit.mockReturnValue({
request
} as any)
await expect(
githubApiHelper.tryGetRepositoryObjectFormat('token', 'owner', 'repo')
).resolves.toEqual({format: '', succeeded: false})
- expect(debugSpy).toHaveBeenCalledWith(
+ expect(mockDebug).toHaveBeenCalledWith(
'Unable to determine repository object format from hash-algorithm endpoint: not found'
)
})
diff --git a/__test__/input-helper.test.ts b/__test__/input-helper.test.ts
index 25b6d18..b2f9074 100644
--- a/__test__/input-helper.test.ts
+++ b/__test__/input-helper.test.ts
@@ -1,10 +1,13 @@
-import * as core from '@actions/core'
-import * as fsHelper from '../lib/fs-helper'
-import * as github from '@actions/github'
-import * as inputHelper from '../lib/input-helper'
+import {
+ jest,
+ describe,
+ it,
+ expect,
+ beforeAll,
+ beforeEach,
+ afterAll
+} from '@jest/globals'
import * as path from 'path'
-import * as workflowContextHelper from '../lib/workflow-context-helper'
-import {IGitSourceSettings} from '../lib/git-source-settings'
const originalGitHubWorkspace = process.env['GITHUB_WORKSPACE']
const gitHubWorkspace = path.resolve('/checkout-tests/workspace')
@@ -12,42 +15,58 @@ const gitHubWorkspace = path.resolve('/checkout-tests/workspace')
// Inputs for mock @actions/core
let inputs = {} as any
-// Shallow clone original @actions/github context
-let originalContext = {...github.context}
+// Mutable mock github context
+const mockGithubContext: any = {
+ ref: 'refs/heads/some-ref',
+ sha: '1234567890123456789012345678901234567890',
+ repo: {owner: 'some-owner', repo: 'some-repo'},
+ eventName: '',
+ payload: {}
+}
+
+// Mock @actions/core before loading input-helper
+jest.unstable_mockModule('@actions/core', () => ({
+ getInput: jest.fn((name: string) => inputs[name]),
+ getBooleanInput: jest.fn((name: string) => inputs[name]),
+ getMultilineInput: jest.fn((name: string) =>
+ inputs[name] ? String(inputs[name]).split('\n').filter(Boolean) : []
+ ),
+ error: jest.fn(),
+ warning: jest.fn(),
+ info: jest.fn(),
+ debug: jest.fn(),
+ setFailed: jest.fn(),
+ setOutput: jest.fn(),
+ setSecret: jest.fn()
+}))
+
+// Mock @actions/github before loading input-helper
+jest.unstable_mockModule('@actions/github', () => ({
+ context: mockGithubContext,
+ getOctokit: jest.fn()
+}))
+
+// Mock fs-helper
+const mockDirectoryExistsSync = jest.fn((p: string) => p === gitHubWorkspace)
+jest.unstable_mockModule('../src/fs-helper.js', () => ({
+ directoryExistsSync: mockDirectoryExistsSync,
+ fileExistsSync: jest.fn()
+}))
+
+// Mock workflow-context-helper
+const mockGetOrganizationId = jest.fn(async () => 123456)
+jest.unstable_mockModule('../src/workflow-context-helper.js', () => ({
+ getOrganizationId: mockGetOrganizationId
+}))
+
+// Dynamic imports after mocking
+const core = await import('@actions/core')
+const inputHelper = await import('../src/input-helper.js')
+type IGitSourceSettings =
+ import('../src/git-source-settings.js').IGitSourceSettings
describe('input-helper tests', () => {
beforeAll(() => {
- // Mock getInput
- jest.spyOn(core, 'getInput').mockImplementation((name: string) => {
- return inputs[name]
- })
-
- // Mock error/warning/info/debug
- jest.spyOn(core, 'error').mockImplementation(jest.fn())
- jest.spyOn(core, 'warning').mockImplementation(jest.fn())
- jest.spyOn(core, 'info').mockImplementation(jest.fn())
- jest.spyOn(core, 'debug').mockImplementation(jest.fn())
-
- // Mock github context
- jest.spyOn(github.context, 'repo', 'get').mockImplementation(() => {
- return {
- owner: 'some-owner',
- repo: 'some-repo'
- }
- })
- github.context.ref = 'refs/heads/some-ref'
- github.context.sha = '1234567890123456789012345678901234567890'
-
- // Mock ./fs-helper directoryExistsSync()
- jest
- .spyOn(fsHelper, 'directoryExistsSync')
- .mockImplementation((path: string) => path == gitHubWorkspace)
-
- // Mock ./workflowContextHelper getOrganizationId()
- jest
- .spyOn(workflowContextHelper, 'getOrganizationId')
- .mockImplementation(() => Promise.resolve(123456))
-
// GitHub workspace
process.env['GITHUB_WORKSPACE'] = gitHubWorkspace
})
@@ -55,6 +74,15 @@ describe('input-helper tests', () => {
beforeEach(() => {
// Reset inputs
inputs = {}
+ jest.clearAllMocks()
+ // Re-apply default mocks
+ ;(core.getInput as jest.Mock<any>).mockImplementation(
+ (name: string) => inputs[name]
+ )
+ mockDirectoryExistsSync.mockImplementation(
+ (p: string) => p === gitHubWorkspace
+ )
+ mockGetOrganizationId.mockResolvedValue(123456)
})
afterAll(() => {
@@ -65,11 +93,8 @@ describe('input-helper tests', () => {
}
// Restore @actions/github context
- github.context.ref = originalContext.ref
- github.context.sha = originalContext.sha
-
- // Restore
- jest.restoreAllMocks()
+ mockGithubContext.ref = 'refs/heads/some-ref'
+ mockGithubContext.sha = '1234567890123456789012345678901234567890'
})
it('sets defaults', async () => {
@@ -95,15 +120,15 @@ describe('input-helper tests', () => {
})
it('qualifies ref', async () => {
- let originalRef = github.context.ref
+ let originalRef = mockGithubContext.ref
try {
- github.context.ref = 'some-unqualified-ref'
+ mockGithubContext.ref = 'some-unqualified-ref'
const settings: IGitSourceSettings = await inputHelper.getInputs()
expect(settings).toBeTruthy()
expect(settings.commit).toBe('1234567890123456789012345678901234567890')
expect(settings.ref).toBe('refs/heads/some-unqualified-ref')
} finally {
- github.context.ref = originalRef
+ mockGithubContext.ref = originalRef
}
})
diff --git a/__test__/ref-helper.test.ts b/__test__/ref-helper.test.ts
index b1578f2..961bc99 100644
--- a/__test__/ref-helper.test.ts
+++ b/__test__/ref-helper.test.ts
@@ -1,8 +1,36 @@
+import {jest, describe, it, expect, beforeEach, afterEach} from '@jest/globals'
import * as assert from 'assert'
-import * as core from '@actions/core'
-import * as github from '@actions/github'
-import * as refHelper from '../lib/ref-helper'
-import {IGitCommandManager} from '../lib/git-command-manager'
+
+// Mutable mock github context
+const mockGithubContext: any = {
+ eventName: '',
+ payload: {},
+ repo: {owner: 'some-owner', repo: 'some-repo'},
+ ref: '',
+ sha: ''
+}
+
+// Mock @actions/core
+const mockDebug = jest.fn()
+jest.unstable_mockModule('@actions/core', () => ({
+ debug: mockDebug,
+ info: jest.fn(),
+ warning: jest.fn(),
+ error: jest.fn(),
+ setFailed: jest.fn()
+}))
+
+// Mock @actions/github
+const mockGetOctokit = jest.fn()
+jest.unstable_mockModule('@actions/github', () => ({
+ context: mockGithubContext,
+ getOctokit: mockGetOctokit
+}))
+
+// Dynamic imports after mocking
+const refHelper = await import('../src/ref-helper.js')
+type IGitCommandManager =
+ import('../src/git-command-manager.js').IGitCommandManager
const commit = '1234567890123456789012345678901234567890'
const sha256Commit =
@@ -12,6 +40,7 @@ let git: IGitCommandManager
describe('ref-helper tests', () => {
beforeEach(() => {
git = {} as unknown as IGitCommandManager
+ jest.clearAllMocks()
})
it('getCheckoutInfo requires git', async () => {
@@ -166,14 +195,12 @@ describe('ref-helper tests', () => {
})
it('getRefSpec sha + refs/tags/ with fetchTags', async () => {
- // When fetchTags is true, only include tags wildcard (specific tag is redundant)
const refSpec = refHelper.getRefSpec('refs/tags/my-tag', commit, true)
expect(refSpec.length).toBe(1)
expect(refSpec[0]).toBe('+refs/tags/*:refs/tags/*')
})
it('getRefSpec sha + refs/heads/ with fetchTags', async () => {
- // When fetchTags is true, include both the branch refspec and tags wildcard
const refSpec = refHelper.getRefSpec('refs/heads/my/branch', commit, true)
expect(refSpec.length).toBe(2)
expect(refSpec[0]).toBe('+refs/tags/*:refs/tags/*')
@@ -194,7 +221,6 @@ describe('ref-helper tests', () => {
})
it('getRefSpec unqualified ref only with fetchTags', async () => {
- // When fetchTags is true, skip specific tag pattern since wildcard covers all
const refSpec = refHelper.getRefSpec('my-ref', '', true)
expect(refSpec.length).toBe(2)
expect(refSpec[0]).toBe('+refs/tags/*:refs/tags/*')
@@ -222,14 +248,12 @@ describe('ref-helper tests', () => {
})
it('getRefSpec refs/tags/ only with fetchTags', async () => {
- // When fetchTags is true, only include tags wildcard (specific tag is redundant)
const refSpec = refHelper.getRefSpec('refs/tags/my-tag', '', true)
expect(refSpec.length).toBe(1)
expect(refSpec[0]).toBe('+refs/tags/*:refs/tags/*')
})
it('getRefSpec refs/heads/ only with fetchTags', async () => {
- // When fetchTags is true, include both the branch refspec and tags wildcard
const refSpec = refHelper.getRefSpec('refs/heads/my/branch', '', true)
expect(refSpec.length).toBe(2)
expect(refSpec[0]).toBe('+refs/tags/*:refs/tags/*')
@@ -248,9 +272,7 @@ describe('ref-helper tests', () => {
'1111111111222222222233333333334444444444555555555566666666667777'
const sha256Base =
'aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffff0000'
- let debugSpy: jest.SpyInstance
- let getOctokitSpy: jest.SpyInstance
- let repoGetSpy: jest.Mock
+ let repoGetSpy: jest.Mock<any>
let originalEventName: string
let originalPayload: unknown
let originalRef: string
@@ -261,10 +283,10 @@ describe('ref-helper tests', () => {
expectedBaseSha: string,
mergeCommit: string
): void {
- ;(github.context as any).eventName = 'pull_request'
- github.context.ref = ref
- github.context.sha = mergeCommit
- ;(github.context as any).payload = {
+ mockGithubContext.eventName = 'pull_request'
+ mockGithubContext.ref = ref
+ mockGithubContext.sha = mergeCommit
+ mockGithubContext.payload = {
action: 'synchronize',
after: expectedHeadSha,
number: 123,
@@ -280,18 +302,18 @@ describe('ref-helper tests', () => {
}
beforeEach(() => {
- originalEventName = github.context.eventName
- originalPayload = github.context.payload
- originalRef = github.context.ref
- originalSha = github.context.sha
+ originalEventName = mockGithubContext.eventName
+ originalPayload = mockGithubContext.payload
+ originalRef = mockGithubContext.ref
+ originalSha = mockGithubContext.sha
- jest.spyOn(github.context, 'repo', 'get').mockReturnValue({
+ mockGithubContext.repo = {
owner: repositoryOwner,
repo: repositoryName
- })
- debugSpy = jest.spyOn(core, 'debug').mockImplementation(jest.fn())
+ }
+
repoGetSpy = jest.fn(async () => ({}))
- getOctokitSpy = jest.spyOn(github, 'getOctokit').mockReturnValue({
+ mockGetOctokit.mockReturnValue({
rest: {
repos: {
get: repoGetSpy
@@ -301,11 +323,11 @@ describe('ref-helper tests', () => {
})
afterEach(() => {
- ;(github.context as any).eventName = originalEventName
- ;(github.context as any).payload = originalPayload
- github.context.ref = originalRef
- github.context.sha = originalSha
- jest.restoreAllMocks()
+ mockGithubContext.eventName = originalEventName
+ mockGithubContext.payload = originalPayload
+ mockGithubContext.ref = originalRef
+ mockGithubContext.sha = originalSha
+ jest.clearAllMocks()
})
it('returns early for SHA-1 merge commit', async () => {
@@ -320,7 +342,7 @@ describe('ref-helper tests', () => {
commit
)
- expect(getOctokitSpy).not.toHaveBeenCalled()
+ expect(mockGetOctokit).not.toHaveBeenCalled()
expect(repoGetSpy).not.toHaveBeenCalled()
})
@@ -338,7 +360,7 @@ describe('ref-helper tests', () => {
sha256Commit
)
- expect(getOctokitSpy).toHaveBeenCalledWith(
+ expect(mockGetOctokit).toHaveBeenCalledWith(
'token',
expect.objectContaining({
userAgent: expect.stringContaining(
@@ -350,10 +372,10 @@ describe('ref-helper tests', () => {
owner: repositoryOwner,
repo: repositoryName
})
- expect(debugSpy).toHaveBeenCalledWith(
+ expect(mockDebug).toHaveBeenCalledWith(
`Expected head sha ${sha256Head}; actual head sha ${actualHeadSha}`
)
- expect(debugSpy).not.toHaveBeenCalledWith('Unexpected message format')
+ expect(mockDebug).not.toHaveBeenCalledWith('Unexpected message format')
})
it('does not match 50-char hex as a valid merge', async () => {
@@ -370,9 +392,9 @@ describe('ref-helper tests', () => {
commit
)
- expect(getOctokitSpy).not.toHaveBeenCalled()
+ expect(mockGetOctokit).not.toHaveBeenCalled()
expect(repoGetSpy).not.toHaveBeenCalled()
- expect(debugSpy).toHaveBeenCalledWith('Unexpected message format')
+ expect(mockDebug).toHaveBeenCalledWith('Unexpected message format')
})
})
})
diff --git a/__test__/retry-helper.test.ts b/__test__/retry-helper.test.ts
index a5d3f79..2cd5026 100644
--- a/__test__/retry-helper.test.ts
+++ b/__test__/retry-helper.test.ts
@@ -1,16 +1,32 @@
-import * as core from '@actions/core'
-import {RetryHelper} from '../lib/retry-helper'
+import {
+ jest,
+ describe,
+ it,
+ expect,
+ beforeAll,
+ beforeEach,
+ afterAll
+} from '@jest/globals'
+
+let info: string[] = []
+
+// Mock @actions/core before loading retry-helper
+jest.unstable_mockModule('@actions/core', () => ({
+ info: jest.fn((message: string) => {
+ info.push(message)
+ }),
+ debug: jest.fn(),
+ warning: jest.fn(),
+ error: jest.fn()
+}))
+
+// Dynamic imports after mocking
+const {RetryHelper} = await import('../src/retry-helper.js')
-let info: string[]
let retryHelper: any
describe('retry-helper tests', () => {
beforeAll(() => {
- // Mock @actions/core info()
- jest.spyOn(core, 'info').mockImplementation((message: string) => {
- info.push(message)
- })
-
retryHelper = new RetryHelper(3, 0, 0)
})
@@ -20,7 +36,6 @@ describe('retry-helper tests', () => {
})
afterAll(() => {
- // Restore
jest.restoreAllMocks()
})
diff --git a/__test__/unsafe-pr-checkout-helper.test.ts b/__test__/unsafe-pr-checkout-helper.test.ts
index 9efa246..fbd854e 100644
--- a/__test__/unsafe-pr-checkout-helper.test.ts
+++ b/__test__/unsafe-pr-checkout-helper.test.ts
@@ -1,10 +1,12 @@
-import * as github from '@actions/github'
-import {assertSafePrCheckout} from '../lib/unsafe-pr-checkout-helper'
-
-// Shallow clone original @actions/github context
-const originalContext = {...github.context}
-const originalEventName = github.context.eventName
-const originalPayload = github.context.payload
+import {
+ jest,
+ describe,
+ it,
+ expect,
+ beforeAll,
+ afterEach,
+ afterAll
+} from '@jest/globals'
const BASE_REPO_ID = 100
const FORK_REPO_ID = 200
@@ -15,9 +17,30 @@ const WORKFLOW_RUN_HEAD_COMMIT_SHA = '4444444444444444444444444444444444444444'
const BASE_QUALIFIED_REPO = 'some-owner/some-repo'
const FORK_QUALIFIED_REPO = 'another-repo/fork'
+// Mutable mock context
+const mockContext: any = {
+ eventName: '',
+ payload: {},
+ repo: {owner: 'some-owner', repo: 'some-repo'},
+ ref: '',
+ sha: ''
+}
+
+jest.unstable_mockModule('@actions/github', () => ({
+ context: mockContext
+}))
+
+// Dynamic imports after mocking
+const {assertSafePrCheckout} = await import(
+ '../src/unsafe-pr-checkout-helper.js'
+)
+
+const originalEventName = mockContext.eventName
+const originalPayload = mockContext.payload
+
function setContext(eventName: string, payload: object): void {
- ;(github.context as {eventName: string}).eventName = eventName
- ;(github.context as {payload: object}).payload = payload
+ mockContext.eventName = eventName
+ mockContext.payload = payload
}
function forkPullRequestTargetPayload(): object {
@@ -59,22 +82,17 @@ function forkWorkflowRunPayload(): object {
describe('unsafe-pr-checkout-helper', () => {
beforeAll(() => {
- jest.spyOn(github.context, 'repo', 'get').mockReturnValue({
- owner: 'some-owner',
- repo: 'some-repo'
- })
+ mockContext.repo = {owner: 'some-owner', repo: 'some-repo'}
})
afterEach(() => {
- ;(github.context as {eventName: string}).eventName = originalEventName
- ;(github.context as {payload: object}).payload = originalPayload
+ mockContext.eventName = originalEventName
+ mockContext.payload = originalPayload
})
afterAll(() => {
- ;(github.context as {eventName: string}).eventName =
- originalContext.eventName
- ;(github.context as {payload: object}).payload = originalContext.payload
- jest.restoreAllMocks()
+ mockContext.eventName = originalEventName
+ mockContext.payload = originalPayload
})
it('allows pull_request events untouched', () => {
diff --git a/__test__/url-helper.test.ts b/__test__/url-helper.test.ts
index 57cb28f..cbe7bc2 100644
--- a/__test__/url-helper.test.ts
+++ b/__test__/url-helper.test.ts
@@ -1,4 +1,5 @@
-import * as urlHelper from '../src/url-helper'
+import {jest, describe, it, expect, beforeEach, afterAll} from '@jest/globals'
+import * as urlHelper from '../src/url-helper.js'
describe('getServerUrl tests', () => {
it('basics', async () => {