Rewrite config.test.ts to test real src/config.ts code, not a mock of it

Co-authored-by: marocchino <128431+marocchino@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2026-03-13 12:42:35 +00:00 committed by marocchino
parent c9caf374bd
commit 88e9b137e7
No known key found for this signature in database
GPG key ID: F54107506CCF18D0

View file

@ -1,139 +1,213 @@
import {afterEach, beforeEach, describe, expect, test, vi} from "vitest" import {afterEach, describe, expect, test, vi} from "vitest"
import {resolve} from "node:path"
const mockConfig = { vi.mock("@actions/core", () => ({
pullRequestNumber: 123, getInput: vi.fn().mockReturnValue(""),
getBooleanInput: vi.fn().mockReturnValue(false),
getMultilineInput: vi.fn().mockReturnValue([]),
setFailed: vi.fn(),
}))
const mockContext = vi.hoisted(() => ({
repo: {owner: "marocchino", repo: "sticky-pull-request-comment"}, repo: {owner: "marocchino", repo: "sticky-pull-request-comment"},
header: "", payload: {} as Record<string, unknown>,
append: false, }))
recreate: false,
deleteOldComment: false,
hideOldComment: false,
hideAndRecreate: false,
hideClassify: "OUTDATED",
hideDetails: false,
githubToken: "some-token",
ignoreEmpty: false,
skipUnchanged: false,
getBody: vi.fn().mockResolvedValue(""),
}
vi.mock("../src/config", () => mockConfig) vi.mock("@actions/github", () => ({
context: mockContext,
}))
beforeEach(() => { const mockGlobCreate = vi.hoisted(() => vi.fn())
mockConfig.pullRequestNumber = 123
mockConfig.repo = {owner: "marocchino", repo: "sticky-pull-request-comment"} vi.mock("@actions/glob", () => ({
mockConfig.header = "" create: mockGlobCreate,
mockConfig.append = false }))
mockConfig.recreate = false
mockConfig.deleteOldComment = false
mockConfig.hideOldComment = false
mockConfig.hideAndRecreate = false
mockConfig.hideClassify = "OUTDATED"
mockConfig.hideDetails = false
mockConfig.githubToken = "some-token"
mockConfig.ignoreEmpty = false
mockConfig.skipUnchanged = false
mockConfig.getBody.mockResolvedValue("")
})
afterEach(() => { afterEach(() => {
vi.resetModules() mockContext.payload = {}
mockContext.repo = {owner: "marocchino", repo: "sticky-pull-request-comment"}
mockGlobCreate.mockReset()
}) })
test("repo", async () => { async function loadConfig(
mockConfig.repo = {owner: "jin", repo: "other"} setup?: (mocks: {core: typeof import("@actions/core")}) => void,
) {
vi.resetModules()
const core = await import("@actions/core")
// vi.resetModules clears the config module cache but not mock instances,
// so reset core back to default values before each test.
vi.mocked(core.getInput).mockReturnValue("")
vi.mocked(core.getBooleanInput).mockReturnValue(false)
vi.mocked(core.getMultilineInput).mockReturnValue([])
setup?.({core})
const config = await import("../src/config") const config = await import("../src/config")
expect(config.repo).toEqual({owner: "jin", repo: "other"}) return {config, core}
}
describe("pullRequestNumber", () => {
test("number_force takes highest priority", async () => {
mockContext.payload = {pull_request: {number: 789}}
const {config} = await loadConfig(({core}) => {
vi.mocked(core.getInput).mockImplementation(name => {
if (name === "number_force") return "456"
if (name === "number") return "123"
return ""
})
})
expect(config.pullRequestNumber).toBe(456)
})
test("falls back to context.payload.pull_request.number", async () => {
mockContext.payload = {pull_request: {number: 789}}
const {config} = await loadConfig()
expect(config.pullRequestNumber).toBe(789)
})
test("falls back to number input", async () => {
const {config} = await loadConfig(({core}) => {
vi.mocked(core.getInput).mockImplementation(name => (name === "number" ? "123" : ""))
})
expect(config.pullRequestNumber).toBe(123)
})
})
describe("repo", () => {
test("defaults to context.repo", async () => {
const {config} = await loadConfig()
expect(config.repo).toEqual({owner: "marocchino", repo: "sticky-pull-request-comment"})
})
test("uses owner and repo inputs when provided", async () => {
const {config} = await loadConfig(({core}) => {
vi.mocked(core.getInput).mockImplementation(name => {
if (name === "owner") return "jin"
if (name === "repo") return "other"
return ""
})
})
expect(config.repo).toEqual({owner: "jin", repo: "other"})
})
}) })
test("header", async () => { test("header", async () => {
mockConfig.header = "header" const {config} = await loadConfig(({core}) => {
const config = await import("../src/config") vi.mocked(core.getInput).mockImplementation(name => (name === "header" ? "my-header" : ""))
expect(config.header).toBe("header") })
expect(config.header).toBe("my-header")
}) })
test("append", async () => { test("append", async () => {
mockConfig.append = true const {config} = await loadConfig(({core}) => {
const config = await import("../src/config") vi.mocked(core.getBooleanInput).mockImplementation(name => name === "append")
})
expect(config.append).toBe(true) expect(config.append).toBe(true)
}) })
test("recreate", async () => { test("recreate", async () => {
mockConfig.recreate = true const {config} = await loadConfig(({core}) => {
const config = await import("../src/config") vi.mocked(core.getBooleanInput).mockImplementation(name => name === "recreate")
})
expect(config.recreate).toBe(true) expect(config.recreate).toBe(true)
}) })
test("delete", async () => { test("deleteOldComment", async () => {
mockConfig.deleteOldComment = true const {config} = await loadConfig(({core}) => {
const config = await import("../src/config") vi.mocked(core.getBooleanInput).mockImplementation(name => name === "delete")
})
expect(config.deleteOldComment).toBe(true) expect(config.deleteOldComment).toBe(true)
}) })
test("hideOldComment", async () => { test("hideOldComment", async () => {
mockConfig.hideOldComment = true const {config} = await loadConfig(({core}) => {
const config = await import("../src/config") vi.mocked(core.getBooleanInput).mockImplementation(name => name === "hide")
})
expect(config.hideOldComment).toBe(true) expect(config.hideOldComment).toBe(true)
}) })
test("hideAndRecreate", async () => { test("hideAndRecreate", async () => {
mockConfig.hideAndRecreate = true const {config} = await loadConfig(({core}) => {
const config = await import("../src/config") vi.mocked(core.getBooleanInput).mockImplementation(name => name === "hide_and_recreate")
})
expect(config.hideAndRecreate).toBe(true) expect(config.hideAndRecreate).toBe(true)
}) })
test("hideClassify", async () => { test("hideClassify", async () => {
mockConfig.hideClassify = "OFF_TOPIC" const {config} = await loadConfig(({core}) => {
const config = await import("../src/config") vi.mocked(core.getInput).mockImplementation(name => (name === "hide_classify" ? "OFF_TOPIC" : ""))
})
expect(config.hideClassify).toBe("OFF_TOPIC") expect(config.hideClassify).toBe("OFF_TOPIC")
}) })
test("hideDetails", async () => { test("hideDetails", async () => {
mockConfig.hideDetails = true const {config} = await loadConfig(({core}) => {
const config = await import("../src/config") vi.mocked(core.getBooleanInput).mockImplementation(name => name === "hide_details")
})
expect(config.hideDetails).toBe(true) expect(config.hideDetails).toBe(true)
}) })
describe("path", () => { test("ignoreEmpty", async () => {
test("when exists return content of a file", async () => { const {config} = await loadConfig(({core}) => {
mockConfig.getBody.mockResolvedValue("hi there\n") vi.mocked(core.getBooleanInput).mockImplementation(name => name === "ignore_empty")
const config = await import("../src/config")
expect(await config.getBody()).toEqual("hi there\n")
}) })
test("glob match files", async () => {
mockConfig.getBody.mockResolvedValue("hi there\n\nhey there\n")
const config = await import("../src/config")
expect(await config.getBody()).toEqual("hi there\n\nhey there\n")
})
test("when not exists return null string", async () => {
mockConfig.getBody.mockResolvedValue("")
const config = await import("../src/config")
expect(await config.getBody()).toEqual("")
})
})
test("message", async () => {
mockConfig.getBody.mockResolvedValue("hello there")
const config = await import("../src/config")
expect(await config.getBody()).toEqual("hello there")
})
test("ignore_empty", async () => {
mockConfig.ignoreEmpty = true
const config = await import("../src/config")
expect(config.ignoreEmpty).toBe(true) expect(config.ignoreEmpty).toBe(true)
}) })
test("skip_unchanged", async () => { test("skipUnchanged", async () => {
mockConfig.skipUnchanged = true const {config} = await loadConfig(({core}) => {
const config = await import("../src/config") vi.mocked(core.getBooleanInput).mockImplementation(name => name === "skip_unchanged")
})
expect(config.skipUnchanged).toBe(true) expect(config.skipUnchanged).toBe(true)
}) })
test("number_force", async () => { test("githubToken", async () => {
mockConfig.pullRequestNumber = 456 const {config} = await loadConfig(({core}) => {
const config = await import("../src/config") vi.mocked(core.getInput).mockImplementation(name => (name === "GITHUB_TOKEN" ? "my-token" : ""))
expect(config.pullRequestNumber).toBe(456) })
expect(config.githubToken).toBe("my-token")
})
describe("getBody", () => {
test("returns message when no path is provided", async () => {
const {config, core} = await loadConfig()
vi.mocked(core.getInput).mockImplementation(name => (name === "message" ? "hello there" : ""))
expect(await config.getBody()).toBe("hello there")
})
test("returns file content when path exists", async () => {
const {config, core} = await loadConfig()
vi.mocked(core.getMultilineInput).mockReturnValue(["__tests__/assets/result"])
mockGlobCreate.mockResolvedValue({
glob: vi.fn().mockResolvedValue([resolve("__tests__/assets/result")]),
})
expect(await config.getBody()).toBe("hi there\n")
})
test("glob matches multiple files", async () => {
const {config, core} = await loadConfig()
vi.mocked(core.getMultilineInput).mockReturnValue(["__tests__/assets/*"])
mockGlobCreate.mockResolvedValue({
glob: vi
.fn()
.mockResolvedValue([
resolve("__tests__/assets/result"),
resolve("__tests__/assets/result2"),
]),
})
expect(await config.getBody()).toBe("hi there\n\nhey there\n")
})
test("returns empty string when path matches no files", async () => {
const {config, core} = await loadConfig()
vi.mocked(core.getMultilineInput).mockReturnValue(["__tests__/assets/not_exists"])
mockGlobCreate.mockResolvedValue({glob: vi.fn().mockResolvedValue([])})
expect(await config.getBody()).toBe("")
})
test("returns empty string and calls setFailed when glob throws", async () => {
const {config, core} = await loadConfig()
vi.mocked(core.getMultilineInput).mockReturnValue(["__tests__/assets/result"])
mockGlobCreate.mockRejectedValue(new Error("glob error"))
expect(await config.getBody()).toBe("")
expect(core.setFailed).toHaveBeenCalledWith("glob error")
})
}) })